我正在尝试使用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);
}
问题是:
当我使用文件描述符在除main之外的其他线程中进行fsync时,是否需要锁定其他线程?
当我在没有互斥量的情况下测试程序时,没有问题。当我阅读fsync的人说明时,它对于不同的线程没有任何帮助。
最佳答案
如果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/