2010-09-09 407 views
1

如果我在不同的線程中多次打開同一文件(.txt文件),則返回的文件描述符將會不同。如果我試圖使用文件描述符寫入(),寫入函數的任何機會都會被阻塞,因爲當多個線程試圖寫入同一個文件時?Linux open()文件描述符

我擔心的是當一個線程調用寫入單個文件,另一個線程調用寫入同一個文件時。那麼第二個線程的寫入會等待第一個線程的寫入先完成嗎?如果是這種情況,我如何確保第二次寫入的調用不會等待,並且如果有第一次寫入就會立即返回,因爲我不希望第二個線程的寫入等待。

感謝

+3

爲什麼不先試試? – Rahul 2010-09-09 05:13:59

+0

是的..我寫了代碼..這個問題是我怎麼知道寫功能被阻止?有關我如何測試的建議? – Leslieg 2010-09-09 05:17:16

+0

Linux中沒有任何東西可以鎖定已經打開的文件。就像拉胡爾說的那樣,試試看看會發生什麼。 – xnine 2010-09-09 05:18:16

回答

3

沒有,但是如果他們正在寫重疊文件的地區最新的write()總是撞早些時候寫道。

一個更常見的問題是關於寫入的文件偏移量,這可能是您的真實問題。在這種情況下,答案是:如果您從每個線程調用open(),則不是。寫入將發生在從最後的write()剩餘的文件偏移量到源自相同原始open()調用的任何描述符,例如由dup()獲取的那些描述符,或者由同一進程中的線程共享。

+0

我可以總結你的上面的句子,如果我只打一個電話打開()並獲得文件描述符,寫入將追加到最後,因此導致它阻止。如果我打開多個調用並獲取不同的文件描述符,它將不會被阻塞,但可能會覆蓋? – Leslieg 2010-09-09 05:38:57

+0

在您提供的條件下,它不會以任何方式阻止,鎖定或同步。 – 2010-09-09 11:19:40

0

您可以在寫入模式下打開文件(在這種情況下,寫入可以互相打開),也可以以追加模式打開(在這種情況下,操作系統將鎖定並確保每次寫入都以原子方式完成,從任何線程 - 直接到文件的新結尾)。

所以,使用追加模式。你的線程會快速將數據轉移到內核隊列中(假設你正在刷新),然後繼續處理事情。如果你發現這個速度還不夠快,那麼你可以嘗試將數據從單個線程轉移到一個專門用於文件更新的線程中,但首先使用更簡單,更清晰的實現,然後使用配置文件來獲得工作系統。

1

如果你有多個線程共享相同的資源(在你的情況下,一個文件),你有責任使用某種類型的同步(例如,信號量或互斥鎖)來確保只有一個寫入正在進行任何時候。否則,結果將不確定。 Unix不會爲你記錄這一點 - 如果你在一個線程中開始寫入,而在另一個線程中寫入同一個文件,則不會發生阻塞。寫入操作將立即完成,不保證對基礎物理設備的I/O操作的順序 - 它們甚至可以交錯。

1

無論你是否使用進程或線程,同時寫入同一個文件很可能會導致問題,除非它非常小心。

文件描述符是否相同也沒關係。

write()在寫入光盤文件時通常不會阻塞,因爲更改只會進入OS緩存。這並不重要,有多少任務正在做這件事。

但是,如果您從多個進程寫入文件,則可能最終會在文件中產生垃圾,因爲寫入的順序不確定。


如果你想寫不同部分在多線程同一文件的,那麼你可以使用PWRITE()寫入到文件中的特定位置,並且多個線程可以共享相同的文件描述。如果你的線程做的是正確的話,這沒關係。

這種技術通常不適用於文本文件。文本文件通常只需一次寫入一個線程即可獲得可預測的內容。