2009-02-27 383 views
7

fprintf是線程安全的嗎? The glibc manual似乎是這樣說的,但我的應用程序使用對fprintf()的單個調用寫入文件似乎是混合來自不同進程的部分寫入。glibc是否執行fprintf()線程安全?

編輯:爲了澄清,問題的程序是lighttpd插件,服務器與多個工作線程運行。

看着這個文件,一些寫入操作混在一起。

編輯2:看來我看到的可能是由於lighttpd的的「工作線程」,其實是分開處理的問題:http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

問題

通過運行2個或多個進程在 相同的套接字,你將有更好的 併發,但將有幾個 的缺點,你必須知道的 :

  • mod_accesslog可能造成破壞的訪問日誌,以相同的文件被打開兩次,不同步。
  • mod_status的將具有Ñ獨立的計數器,對每個 處理一組。
  • mod_rrdtool將因兩次接收相同的時間戳而失敗。
  • mod_uploadprogress將不顯示正確的狀態。
+0

你在用`fprintf`編寫的文件中觀察到這一點,還是在`stdout`和`stderr`流中觀察了這個? – 2009-02-27 14:41:11

回答

14

你混淆了兩個概念 - 從多個線程寫入和從多個進程寫入。

在一個進程中,可以確保在下一個允許訪問輸出緩衝區之前完成一次fprintf的調用,但是一旦您的應用程序將輸出輸出到一個文件,您將受到OS的擺佈。如果沒有某種基於OS的鎖定機制,則無法確保完全不同的應用程序不會寫入日誌文件。

7

聽起來像你需要閱讀file locking。您遇到的問題是多個進程(即不是線程)正在同時寫入同一文件,並且沒有可靠的方法來確保寫入是原子性的。這會導致文件覆蓋彼此的寫入,混合輸出和完全不確定的行爲。

這有什麼好做的是線程安全,因爲這只是在單進程多線程程序有關。

2

當前的C++標準沒有提及併發性,也沒有1990 C標準。 (我沒有閱讀1999 C標準,所以不能評論它;即將出現的C++ 0x標準確實說了些什麼,但我不知道什麼是非正式的。)

這意味着fprintf( )本身可能既不是線程安全的,也不是其他的,並且取決於實現。我會仔細閱讀glibc文檔中關於它的內容,並將其與您正在做的事情進行比較。