2012-07-24 37 views
1

在多分叉進程之間是否存在任何緩衝區限制或POSIX/Linux中共享標準錯誤的特定準則?在多個分叉進程之間共享perror

perror("Some descriptor related error: "); 

我有一個服務器應用程序,在需要時調用perror。作爲一個單一的過程,它工作正常。在使用fork創建多個進程的情況下,在運行服務器一段時間(發生多次打印錯誤)後,它會不斷打印錯誤語句並進入無限循環。

我通過註釋掉服務器正常運行的打印語句來驗證。

因此,在我看來,可能會出現一些緩衝區溢出類型的標準錯誤,在一段時間後運行。

我沒有使用任何互斥或信號反對perror。

服務器代碼很大,它使用epoll處理多個客戶端描述符和工作進程池,這些工作進程會在客戶端來臨時提取客戶端。

回答

1

你需要記住的是,雖然I/O可能是線程安全取決於平臺,輸出到stderrstdout上不多進程安全 ...因此,如果你有多個進程寫終端輸出,如果沒有進程間同步機制使每個寫入原子化,它們將最終彼此相互寫入。當我說「原子」時,我指的是你想從每個過程寫出每條消息的全部長度......你可能最終得到的是每條消息的碎片從不同的過程中被粉碎成每個人訪問終端緩衝區並且在必須屈服於競爭終端緩衝區資源的下一個進程之前,自動寫入多個字節,但不是每個消息中的全部字節數。

現在,您的無限循環可能是由一個進程造成的......如果您註釋掉所有錯誤語句,您怎麼能知道服務器正在「完美」工作?例如,如果只有一個分叉的進程死鎖,其餘的進程可能沒問題,而且事實上,當你實際上只是掩蓋了這個錯誤而沒有消除它時,服務器似乎正常運行。

+0

謝謝,我明白了。但是我能否依靠這樣一個事實,即由於輸出否則看起來完全完整和連續,即直到無限循環打印錯誤開始時才被覆蓋,所以這個覆蓋不是原因?我的意思是我應該看到一些重疊印刷呢?而不是連續重複但完整的恐怖控制檯打印? – fayyazkl 2012-07-24 15:49:17

+1

儘管問題是關於多處理*,而不是多線程*,stdio庫通常是線程安全的(GNU libc實現當然是) - 如果從多個線程同時調用'fprintf',兩個消息將按照某種順序序列化,但是每條消息都將是完整的和完整的。 'write(2)'系統調用是原子性的,所以同時從多個進程寫入同一個文件描述符的行爲再次表現良好,你只是不知道寫入的順序。 – 2012-07-24 15:55:05

+0

即使「stderr」是有一個緩衝區溢出的問題,輸出緩衝區在終端進程中使用的內存不與正在運行的進程的內存共享,所以如果終端出現這樣的錯誤,您不能損壞正在運行的進程堆棧或堆棧緩衝區是存在的......重複打印的錯誤很可能是某個運行分叉進程進入無限循環的問題。 – Jason 2012-07-24 15:55:12