2011-08-24 112 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