并发使用多个线程写入文件

我有一个用户级别的程序,它使用标志O_WRONLY|O_SYNC打开一个文件。 该程序创build256个线程,试图将每个数据的256个或更多的字节写入文件。 我希望总共有1280000个请求,总计大约有300MB的数据。 一旦1280000个请求完成,程序结束。

我使用pthread_spin_trylock()来增加一个跟踪已完成请求数量的variables。 为了确保每个线程都写入一个唯一的偏移量,我使用pwrite()并根据已经写入的请求数来计算偏移量。 因此,在写入文件时,我不使用任何互斥锁(这种方法确保数据完整性吗?)

当我检查pwrite()调用被阻塞的平均时间和使用blktracefind的相应数字(即平均Q2C时间 – 这是BIOs整个生命周期的时间的度量)时,我发现这是有显着的差异。 实际上,给定BIO的平均完成时间远远大于pwrite()调用的平均等待时间。 这种差异背后的原因是什么? 这些数字不应该相似,因为O_SYNC确保数据在返回之前实际写入物理介质?

Solutions Collecting From Web of "并发使用多个线程写入文件"

假设pwrite()是原子的,所以你应该在那里安全…

关于系统调用和实际BIO之间的延迟差异,根据kernel.org上有关open(2)的手册页的信息:

POSIX提供了三种不同的同步I / O变量,对应于标志O_SYNC,O_DSYNC和O_RSYNC。 目前(2.6.31),Linux只实现O_SYNC,但glibc将O_DSYNC和O_RSYNC映射为与O_SYNC相同的数值。 大多数Linux文件系统实际上并没有实现POSIX O_SYNC语义,它要求所有的写入元数据更新在返回到用户空间时都在磁盘上,而只需要O_DSYNC语义,它只需要实际的文件数据和元数据来检索它在系统调用返回时在磁盘上。

因此,这基本上意味着,使用O_SYNC标志,您尝试写入的所有数据不需要在系统调用返回之前刷新到磁盘,而只需要足够的信息即可从磁盘中检索它。在你正在编写的内容上,这可能比你打算写入磁盘的整个数据缓冲区要少得多,因此所有数据的实际写入都会在系统调用完成之后完成了,这个过程已经转移到别的东西上了。