簡體   English   中英

同時讀寫文件

[英]Reading and writing files concurrently

在Linux上,如果一個腳本正在讀取一個(大)文件,而另一個腳本正在嘗試寫入同一文件,那么兩個操作都將成功,以便第一個腳本讀取未損壞的數據(由於inode)嗎? (假設我正在使用file_get_contentsfile_put_contents

“最正確”的答案是:

盡管縮略語要復雜一些:兩種操作都將成功,並且從嚴格意義上講,您將永遠不會看到損壞的數據。 但是,您看到的數據可能不一致。 這意味着,如果您寫“ ABC”,那么在有人讀取之前可以寫“ AB”(並且最后的數據將是文件之前的內容),但是“ ABC”將永遠不會損壞為“ pnt”或“ CDQ”。
此外,如果兩個進程同時寫入,則有可能在實現另一次寫入之前僅實現一部分寫入。 例如,同時寫入“ ABCDEF”和“ 123456” 可能會導致“ A2C4E6”存儲在緩沖區高速緩存中,然后存儲在磁盤上。 它還可能會導致“ ABCDEF”或“ 123456”。 同時讀取的第三個進程可能會選擇任何可能的組合。

一般而言,讀寫不保證是原子的。 readvwritev系統調用是例外,只要它們被保證是原子(上的文件,至少)。 但是,這不是“正常”所寫的內容。

此外,通常會進行庫級緩存,因此,除了不一定在緩沖區緩存中進行讀寫操作外,同時進行讀寫操作的兩個過程可能對文件內容有不同的看法。

附加到文件(非並發)並同時讀取通常是“安全的”。 並非所有數據在您讀取時都可見,但是無論您寫什么,都將完全按照您寫的方式結束。

請注意, 某些 PHP函數將在某些體系結構上使用文件映射,這會使事情變得更加復雜。

作為對編輯的答復: file_get_contentsfile_put_contents正是前面提到的一些函數,這些函數將在某些體系結構上使用內存映射。
雖然沒有具體說明哪個體系結構,但是Linux是一個相當安全的選擇。
現在,內存映射的麻煩在於,兩個同時訪問文件的進程實際上是在同時訪問同一物理內存。 這意味着,如果沒有顯式同步,讀取和寫入也不是原子的。

另外,您沒有形式上的保證(盡管實現實際上是保證的,因為Linux具有統一的虛擬內存系統),除非調用了msync否則內存中的視圖對應於外部可觀察到的磁盤上的表示形式。 這意味着從理論上(盡管不是在實踐中),使用正常的讀寫操作(而不是使用內存映射)的不同過程可能會看到完全不同的東西。

暫無
暫無

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

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