2011-08-24 116 views
4

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

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

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

回答

3

pwrite()被假定是原子,所以你应该是安全有...

在问候你的系统调用和实际BIO之间的等待时间的差异,根据对man-pages at kernel.org开放该信息(2 ):

POSIX提供用于对应于 标志O_SYNC,O_DSYNC和O_RSYNC同步的I/O的三个不同的变体, 。目前(2.6.31), Linux只有 实现了O_SYNC,但glibc将O_DSYNC和O_RSYNC映射为 数值为 的值为O_SYNC。大多数Linux文件系统实际上并不 实现POSIX O_SYNC语义,这需要一个写 的所有元数据更新是在磁盘上 在返回给用户空间,但只有O_DSYNC语义, 仅需要 实际文件数据和必要的元数据将其恢复为 磁盘时系统调用返回时的 。

所以这基本上意味着,与O_SYNC标志你试图写入数据的整体不需要系统调用返回前被刷新到磁盘,而仅仅是足够的信息能够检索及它来自磁盘......取决于你正在写的内容,这可能比你打算写入磁盘的整个数据缓冲区要低很多,因此所有数据的实际写入将发生在以后的时间,系统调用完成后,进程已转移到其他方面。

+0

我重复了ext2文件系统的相同实验,与ext3文件系统不同,它不是日志文件系统。平均Q2C延迟结果为8.5毫秒。在用户级程序中,'pwrite()'调用被阻塞的平均时间为1.5毫秒。与我之前的实验相比,这些数字相对更接近;然而,这不是我想要的。我怎样才能调用'pwrite()'_completely_ synchronous,即只有在整个数据缓冲区写入磁盘之后调用才会返回?磁盘基准测试工具必须有解决方法? – user745878

+0

您可能将不得不使用较低的内核级写入原语......在Linux实现中,“pwrite()”并不完全同步。 – Jason