簡體   English   中英

如何從兩個進程同步 - 在一個文件上進行原子寫入?

[英]How can I synchronize — make atomic — writes on one file from from two processes?

我有兩個進程,每個進程寫大數據緩沖區,我想控制同步這些進程的寫入到一個文件。

處理1寫入緩沖器A包括(A1,A2,A3)和處理2寫入緩沖器B,包括(B1,B2,B3)。 當我們使用write()系統調用將這些緩沖區寫入磁盤到同一個文件時(整個緩沖區一次write(fd, A, sizeof(A))write(fd, A, sizeof(A)) ),文件架構如何?

  • 它是這樣的:A,B或B,A可能嗎?
  • 或者它可能是這樣的:A1,A2,B1,A3,......

我問這個是因為系統調用是原子的。 如果我們寫的數據緩沖區太大會發生什么。 它是否像常規磁盤文件的管道?

如果要存在兩個緩沖區的內容,則必須打開設置了O_APPEND標志的文件。 append標志在寫入之前尋找文件的末尾。 如果沒有這個設置,兩個進程可能都指向文件的相同或重疊區域,而最后寫入的任何一個將覆蓋另一個寫入的內容。

每次write調用都會寫入所請求的字節數。 如果您的進程被信號中斷,那么您最終可以進行部分寫入 - 返回寫入的實際字節數。 無論你是否寫入了所有的字節,你都會編寫一個連續的文件部分。 你沒有得到你提到的交錯效果作為你的第二種可能性(例如A1,B1,A2,B2,......)。

如果您只進行部分寫作,您的工作方式取決於您。 您可以繼續寫入(從緩沖區開始偏移先前寫入的字節數),也可以放棄寫入的其余部分。 只有這樣才能獲得交錯效果。

如果在另一個進程寫入之前讓一個寫入的內容完成很重要,那么在嘗試寫入任何數據之前,您應該考慮鎖定該文件以進行獨占寫入訪問(兩個進程都必須檢查)。

假設緩沖區大小相等,結果將是A或B,具體取決於最后安排的進程。

write系統調用是原子的,是的,這意味着結果將是A或B,而不是兩者的混合。

假設您希望文件中同時包含A和B,則可以使用O_APPEND打開該文件; 請注意,這不適用於NFS。

另一個選擇是每個進程跟蹤它應該使用哪個文件偏移量,並使用lseek()或pwrite()

對於訪問該文件的程序,您肯定需要某種形式的同步,否則最終會出現混亂的文件內容。 write系統調用可以寫入比您請求的更少的字節,因此您的塊A1,A2或B1,B2可能只是部分寫入。 這可能經常發生,或很少發生,具體取決於許多條件。 如果它只在一周內發生一次,那么您將遇到一個可能很難檢測到的錯誤。

作為解決方案,您可以使用文件鎖定( man 2 flockman fcntl並搜索鎖定)。 另一種可能性是使用信號量( man -k semaphore )來同步你的程序寫入或一些其他形式的IPC。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM