gpt4 book ai didi

c++ - 不同线程中的 fsync() 和 write()

转载 作者:太空狗 更新时间:2023-10-29 11:44:49 27 4
gpt4 key购买 nike

我正在尝试使用 fsync() 和 write() 编写程序,但 fsync 需要时间来同步数据,但我没有时间等待。我为 fsync() 创建了一个线程这是我的代码:

#include <thread>
void thread_func(int fd) {
while (1) {
if(fsync(fd) != 0)
std::cout << "ERROR fsync()\n";
usleep(100);
}
}
int main () {
int fd = open ("device", O_RDWR | O_NONBLOCK);
if (fd < 0) {
std::cout << "ERROR: open()\n";
return -1;
}
std::thread *thr = new std::thread (thread_func, fd);
if (thr == nullptr) {
std::cout << "Cannot create thread\n";
close (fd);
return -1;
}
while (1) {
if (write (fd, 'x', 1) < 1)
std::cout << "ERROR write()\n";
}
close(fd);
}

问题是:

当我在除主线程之外的其他线程中使用文件描述符进行 fsync 时,是否需要锁定不同的线程?当我在没有互斥量的情况下测试我的程序时,它没有问题。当我阅读 fsync 的 man 描述时,它对不同的线程没有任何帮助。

最佳答案

如果 fsync 需要时间,甚至有时会阻塞很短的时间这一事实是一个问题,那么您很可能做错了什么。

通常,您根本不想调用fsync。这样做是一种严重的反优化,只有在必须确保数据已写出1 时才会愿意这样做。然而,在这种情况下,您绝对希望 fsync 阻塞,这不仅符合预期,而且是必要的。
只有当 fsync 返回时,您才知道它已经完成了它的任务。您知道操作系统已尽最大努力确保数据已写入,只有这样才能安全地继续。如果您将其卸载到后台线程,您也可以不调用 fsync,因为您不知道何时可以安全地假定数据已写入。

如果启动写入是您的主要目标,您可以在 Linux(异步运行)下使用 sync_file_range,稍后再调用 fsync。跟进 fsync 的原因既是为了确保写入完成,也是 sync_file_range 不更新元数据的事实,所以除非你严格覆盖已经分配的数据文件,即使数据在磁盘上,即使发生崩溃,您的写入也可能不可见(我无法想象会发生这种情况,因为为文件分配更多扇区必然意味着必须修改元数据,但联机帮助页明确警告这可能发生)。


1 fsync 函数仍然不能(也不能)保证数据在永久存储上,它可能仍在缓存层次结构中的某个位置,例如 Controller 或磁盘的写入缓存。

关于c++ - 不同线程中的 fsync() 和 write(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22760084/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com