使用多个线程并发写入文件
我有一个用户级程序,它使用标志 O_WRONLY|O_SYNC
打开文件。该程序创建 256 个线程,每个线程尝试将 256 个或更多字节的数据写入文件。我想要总共 1280000 个请求,使其总共约 300 MB 的数据。一旦完成 1280000 个请求,该计划就会结束。
我使用 pthread_spin_trylock() 来增加一个变量,该变量跟踪已完成的请求数。为了确保每个线程写入唯一的偏移量,我使用 pwrite() 并根据已写入的请求数计算偏移量。因此,在实际写入文件时,我不使用任何互斥体(这种方法是否确保数据完整性?)
当我检查 pwrite()
调用被阻止的平均时间以及相应的数字时(即平均 Q2C 时间——这是 BIO 完整生命周期的时间度量)使用 blktrace
,我发现有明显的区别。事实上,给定 BIO 的平均完成时间远大于 pwrite()
调用的平均延迟。这种差异背后的原因是什么?由于 O_SYNC
确保数据在返回之前实际写入物理介质,这些数字不应该相似吗?
I have a userlevel program which opens a file using the flags O_WRONLY|O_SYNC
. The program creates 256 threads which attempt to write 256 or more bytes of data each to the file. I want to have a total of 1280000 requests, making it a total of about 300 MB of data. The program ends once 1280000 requests have been completed.
I use pthread_spin_trylock()
to increment a variable which keeps track of the number of requests that have been completed. To ensure that each thread writes to a unique offset, I use pwrite()
and calculate the offset as a function of the number of requests that have been written already. Hence, I don't use any mutex when actually writing to the file (does this approach ensure data integrity?)
When I check the average time for which the pwrite()
call was blocked and the corresponding numbers (i.e., the average Q2C times -- which is the measure of the times for the complete life cycle of BIOs) as found using blktrace
, I find that there is a significant difference. In fact, the average completion time for a given BIO is much greater than the average latency of a pwrite()
call. What is the reason behind this discrepancy? Shouldn't these numbers be similar since O_SYNC
ensures that the data is actually written to the physical medium before returning?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
pwrite()
被认为是原子的,所以你应该是安全的......关于你的系统调用和实际 BIO 之间的延迟差异,根据 kernel.org 上的手册页 用于 open(2 ):
因此,这基本上意味着,使用 O_SYNC 标志,您尝试写入的全部数据不需要在系统调用返回之前刷新到磁盘,而只需足够的信息即可< em>从磁盘检索它...取决于您正在写入的内容,这可能比您打算写入磁盘的整个数据缓冲区要少得多,因此所有数据的实际写入数据将在稍后的时间发生,之后系统调用已完成,该过程已转移到其他事情。
pwrite()
is suppose to be atomic, so you should be safe there ...In regards to the difference in latency between your syscall and the actual BIO, according to this information on the man-pages at kernel.org for open(2):
So this basically implies that with the
O_SYNC
flag the entirety of the data you're attempting to write does not need to be flushed to disk before a syscall returns, but rather just enough information to be capable of retrieving it from disk ... depending on what you're writing, that could be quite a bit less than the entire buffer of data you were intending to write to disk, and therefore the actual writing of all the data will take place at a later time, after the syscall has been completed and the process has moved on to something else.