操作系統是否正確處理它?或者我會不得不打電話給flock()?如果同時通過2個不同進程在同一文件上調用寫入系統調用,會發生什麼情況
回答
雖然OS不會崩潰,並且文件系統不會被破壞,呼籲write()
是不保證的廣告是原子,除非有問題的文件描述符是一個管道,數據量是寫入的是PIPE_MAX
字節或更少。的the standard相關部分:
嘗試寫一個管道或FIFO有幾個主要特點:
- 原子/非原子:寫是原子的,如果寫在一個操作中的全部金額不與來自任何其他進程的數據交錯。當有多個寫入者將數據發送給單個閱讀器時,這非常有用。應用程序需要知道有多大的寫入請求可以被期望以原子方式執行。這個最大值被稱爲{PIPE_BUF}。 IEEE Std 1003.1-2001的這一卷沒有說明大於{PIPE_BUF}字節的寫請求是否是原子的,但是要求{PIPE_BUF}或更少字節的寫入是原子的。
[...]
因此,在原則上,你必須同時鎖定的作家,或者你寫入的數據可能會混淆和亂序(甚至相同的寫入內)或你可能有多個寫入相互覆蓋。然而,有一個例外 - 如果你通過O_APPEND
,你寫將得到有效原子:
如果文件狀態標誌的O_APPEND標誌設置,文件偏移應被設置爲文件結束前對於每次寫入,在改變文件偏移和寫入操作之間不會發生中間文件修改操作。
雖然這並不一定是原子相對於非O_APPEND
寫,或同時讀取,如果所有的作家使用O_APPEND
,和你做一個read
前莫名其妙地同步,你應該沒問題。
我不認爲'O_APPEND'使寫入原子化。您所引用的所有內容都表明,寫入將始終發生在文件末尾。與'O_APPEND'同時寫入的兩個進程不會破壞對方的寫入,但它們仍然可以交錯進行。 –
@R ..這是真的,但是如果兩個進程每個都發出一個單獨寫入PIPE_BUF字節或更少的字節到與O_APPEND打開的同一個文件(兩端),那麼這些寫入將不會交織 – bdonlan
O_APPEND文本沒有任何內容與管道有關。管道總是附加的。該文本是關於普通文件的,PIPE_BUF文本不適用於普通文件。 –
當然,內核會正確處理它,因爲內核的正確性 - 這是正確的定義。
如果你有一套coöperatingflockers,那麼你可以使用內核來排隊大家。但請記住,羣與I/O無關:它不會阻止其他人寫入文件。它至多隻會干擾其他植物。
write
(和writev
)也保證原子性。
這意味着如果兩個線程或進程同時寫入,則不能保證哪一個先寫入。 但是你確實保證一個系統調用中的任何內容都不會與另一個系統調用的數據混合在一起。
只要始終正常工作,但不一定如您所期望的那樣(如果您認爲過程A出現在過程B之前)。
我唯一的要求是,如果線程-A寫入一堆線(比如線-A)並且線程-B寫入一組線(比如線-B),則輸出是整行-A後跟線-B或整行-B後面跟着-A。我不想讓一半的行-A寫在行間-B。只要A線和B線完全承諾,而其他線程不會在其中間輸出它,我不在乎。我不關心線-A和線-B之間的相關順序的順序。 (線A,線B)是可以接受的。 (line-B,lines-A)也是可以接受的 – user855
'write'和'writev'保證原子性只有管道或FIFO小於'PIPE_MAX'的寫入,我相信 - 除非您另有引用。 – bdonlan
@bdonlan:例如'writev'的這個措辭(沒有爲'write'搜索):_「由readv()和writev()執行的數據傳輸是原子的:writev )被寫爲一個單獨的塊,與其他進程中的寫入輸出不混合(但請參閱管道(7)中的例外情況)「@ – Damon
當然,它會正常工作。它不會使操作系統或進程崩潰。
它是否有意義取決於應用程序的寫入方式和文件的用途。
如果文件被所有進程打開爲append-only,則每個進程(在概念上)在每次寫入之前執行原子對齊操作;這些保證不會覆蓋彼此的數據(但當然,順序是不確定的)。
在任何情況下,如果您使用一個可能會將單個邏輯寫入分割爲多個寫入系統調用的庫,可能會出現問題。
write()
,writev()
,read()
,readv()
可以生成部分寫入/讀出,其中所傳送的數據量小於被請求的是什麼小。
報價爲writev()
Linux手冊頁:
注意,這並不是一個成功的調用比傳輸的字節數更少的錯誤要求
引述POSIX手冊頁:
如果write()在成功寫入一些數據後被信號中斷,它將返回寫入的字節數。
AFAIU,O_APPEND
不不幫助在這方面,因爲它沒有阻止部分寫道:它不僅保證,無論數據被寫入到文件的末尾附加。
看到這個bug report from the Linux kernel:
一種方法是寫一個消息文件。 [...]寫入可以分成兩部分。 [...]所以如果信號到達,寫入被中斷。 [...]這是完全合法的行爲,儘可能規範(POSIX,SUS,...)而言
FIFO和PIPE寫入小於PIPE_MAX
但保證是原子的。
- 1. 如果2臺或更多服務器試圖同時寫入同一文件,NFS會發生什麼情況?
- 2. 如果mysql_insert_id同時調用不同的地方和不同的瀏覽器,會發生什麼情況?
- 3. 如果兩個不同的程序試圖同時寫入同一個文件,會發生什麼?
- 4. 當多個進程嘗試寫入同一個文件時會發生什麼?
- 5. 線程通過另一個類調用同步方法時會發生什麼?
- 6. 如果在Android中使用不同的參數多次調用相同的AsyncTask,會發生什麼情況
- 7. 如果在同步ajax調用之後進行異步ajax調用,會發生什麼情況?
- 8. Hadoop - 當多個進程試圖同時寫入同一個文件時會發生什麼?
- 9. 如果2個或更多人試圖同時更新同一個MySQL表,會發生什麼情況?
- 10. 如果兩個內核嘗試同時寫入主內存中的相同位置,會發生什麼情況?
- 11. 如果寫入文件失敗,會發生什麼情況?
- 12. 如果我不調用transaction.close或transaction.rollback,會發生什麼情況?
- 13. 如果兩個用戶同時鎖定互斥鎖,會發生什麼情況?
- 14. 2個線程寫入同一個對象時會發生什麼?
- 15. 在什麼情況下會調用iOS系統推送通知?
- 16. 如果在同一平臺上有兩個或更多不同的jre實現,會發生什麼情況?
- 17. 如果我在不同佈局的多個小部件中使用相同的id,會發生什麼情況?
- 18. 當我讀/寫同一個文件時會發生什麼?
- 19. 如果未安裝代碼合同,會發生什麼情況?
- 20. 如果在同一個進程中使用.NET 1.1和.NET 2.0 COM對象,會發生什麼情況?
- 21. 如果程序在僅EABI內核中生成OABI樣式的系統調用,會發生什麼情況?
- 22. 從不同線程同時寫入套接字時會發生什麼?
- 23. 在ARMv8中,如果全局頁表條目在不同進程間發生衝突,會發生什麼情況?
- 24. 如果同時從多個pthread中調用CUDA內核,會發生什麼情況?
- 25. phonegap-plugin-contentsync同步後文件會發生什麼情況?
- 26. 如果我在未使用的pthread_t上調用pthread_join()會發生什麼情況?
- 27. 如果你在同一個集合上調用兩次相同的迭代器會發生什麼?
- 28. 如果進程調用屬於另一個進程的代碼,會發生什麼情況?
- 29. 在CUDA中,如果多線程「競爭性寫入」到同一位置會發生什麼情況?
- 30. php的疑惑。如果兩個人同時訪問同一個腳本,會發生什麼情況?
什麼是「正確」?你期望發生什麼? –
這取決於操作系統。 –
[相似問題](http://stackoverflow.com/questions/7187830/what-happens-when-multiple-processes-try-to-read-from-the-same-pipe/7188349#7188349) –