當寫入開始或完成時,inotify 是否會觸發通知?

當寫入開始或完成時,inotify 是否會觸發通知?

想像一下兩個進程,一個讀取器和一個寫入器,透過 ext3 檔案系統上的常規檔案進行通訊。 ReaderIN_MODIFY對文件有 inotify監視。 Writer 在一次呼叫中將 1000 個位元組寫入檔案write()。 Reader 取得 inotify 事件,並呼叫fstat該檔案。讀者看到了什麼?

  1. 是否能保證讀者能獲得至少 1000 美元的st_size文件賠償?從我的實驗來看,似乎不是。

  2. 是否能保證Reader實際上可以讀取read()1000位元組?

這種情況發生在嚴重 I/O 綁定的盒子上。例如,sar顯示大約 1 秒的等待時間。在我的例子中,Reader 實際上在呼叫 之前在獲取 inotify 事件後等待 10 秒stat,並且得到的結果太小。

我所希望的是在文件準備好之前不會傳遞 inotify 事件。我懷疑實際發生的是 inotify 事件write()在 Writer 中的呼叫期間觸發,並且只要數據恰好準備好,數據實際上就可供系統上的其他進程使用。在這種情況下,10s 的時間是不夠的。

我想我只是在尋找核心是否確實按照我猜測的方式實現 inotify 的確認。另外,是否有任何選擇可能可以改變這種行為?

最後,考慮到這種行為,inotify 的意義何在?無論如何,在收到事件後,您都只能輪詢檔案/目錄,直到資料實際可用。不如一直這樣做,而忘記 inotify。

***編輯**** 好吧,正如經常發生的那樣,我所看到的行為實際上是有道理的,現在我明白了我真正在做什麼。 ^_^

我實際上是在響應文件所在目錄上的 IN_CREATE 事件。

我將更改我的程式碼,以便一旦收到 IN_CREATE 事件,我將訂閱檔案本身的 IN_MODIFY,並且在收到 IN_MODIFY 事件之前我不會真正嘗試讀取檔案。我意識到那裡有一個小窗口,我可能會錯過對文件的寫入,但這對於我的應用程式來說是可以接受的,因為在最壞的情況下,文件將在最大秒數後關閉。

答案1

從我所看到的核心原始碼,inotify 僅在寫入完成後才會啟動(即您的猜測是錯誤的)。觸發通知後,實作系統sys_write呼叫的函數只會發生兩件事write:設定一些調度程序參數,並更新檔案描述符上的位置。這段程式碼早在2.6.14。當通知觸發時,檔案已經有了新的大小。

檢查是否有可能出錯的地方:

  • 也許讀者收到的是以前寫的舊通知。
  • 如果讀者打電話stat然後又打電話read,反之亦然,那麼中間可能會發生一些事情。如果您繼續向文件追加內容,則stat首先調用可以保證您能夠讀取到那麼遠,但在讀取器調用時可能已經寫入了更多數據read,即使它尚未收到 inotify 通知。
  • 僅僅因為編寫器呼叫write並不意味著核心將寫入請求的字元數。很少有情況可以保證原子寫入會達到任意大小。然而,每個write呼叫都保證是原子的:在某些時候資料還沒有寫入,然後突然n位元組已寫入,其中n是調用的返回值write。如果您觀察到部分寫入的文件,則表示write傳回的文件小於其大小參數。

用於調查正在發生的情況的有用工具包括:

  • strace -tt
  • 審計子系統

相關內容