2009-09-11 66 views
3

我有一個程序,其中:推理PTHREAD問題()

  • 具有主螺紋(1),其啓動服務器螺紋(2)和另一個(4)。
  • 服務器線程(2)執行accept(),然後創建一個新線程(3)來處理連接。

在某些時候,線程(4)執行一個fork/exec來運行另一個應該連接到線程(2)正在監聽的套接字的程序。有時這會失敗或者花費時間過長,並且診斷極其困難。如果我對系統進行strace,看起來fork/exec已經工作,接受已經發生,新的線程(4)已經創建..但是在那個線程中沒有任何反應(使用strace -ff,相關pid的文件是空白的)。

任何想法?

+0

你的主線程(1)在創建(2)和(4)後做了什麼?它是永遠等待(2)還是等到某種狀況? – Los 2009-09-11 18:13:06

+0

(1)進入並等待鍵盤輸入(使用與readline非常相似的東西),它形成命令,通過鎖定的隊列移交給(4)。 – pjc50 2009-09-14 09:51:21

回答

2

我得出的結論,這可能是這樣的現象:

http://kerneltrap.org/mailarchive/linux-kernel/2008/8/15/2950234/thread

的錯誤是很難引起我們的發展系統,但一般是由大型共享計算機上運行的用戶報告;分叉的應用程序也啓動一個JVM,它本身分配了很多線程。這個問題也與正在加載的機器和大量的內存使用有關(我們有一臺128Gb內存的機器,進程可能是10-100G)。

我一直在閱讀O'Reilly pthreads書,它解釋了pthread_atfork(),並建議在啓動時從主進程派生出來的「代理父進程」使用哪個子進程運行。它還建議使用預先創建的線程池。這兩個看起來都是好點子,所以我會至少實施其中一個。

0

將代碼縮小到仍然具有該行爲的最小可能大小並在此處發佈。要麼你會找到答案,要麼我們將能夠追蹤它。

順便說一句 - http://lists.samba.org/archive/linux/2002-February/002171.html似乎exec的pthread行爲沒有很好的定義,可能取決於你的操作系統。

你在fork和exec之間有任何代碼嗎?這可能是一個問題。

+0

該鏈接似乎描述了exec沒有fork的問題,這可能不是一回事。 fork和exec之間沒有太多的代碼; fork/exec實際上是在Tcl解釋器中完成的(使用tcl的「exec ...&」) 小型測試用例可能很困難,因爲我無法可靠地用巨大的應用程序來重現它。 – pjc50 2009-09-11 16:05:13

+0

看看這個http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html。如果在那裏沒有你的代碼,可能會有一些代碼注入信息叉。請準備最小的例子。 – agsamek 2009-09-11 16:13:43

+0

>小型測試用例可能很困難,因爲我無法可靠地重現它與巨大的應用程序。 --- pjc50:這是我們如何調試代碼。我們不猜。我們跟蹤錯誤。如果你有兩種情況 - 一種是產生錯誤的大小,另一種是小的,那麼你就接近找到它。只需刪除大塊代碼並檢查錯誤是否仍然存在。看看這裏http://en.wikipedia.org/wiki/Binary_search_algorithm,做你的功課,讓我們知道是什麼問題。 – agsamek 2009-09-12 17:09:28

1

這看起來像是一個死鎖狀態。尋找阻塞函數,如accept(),問題應該在那裏。

0

對於多線程和fork非常小心。大多數glibc/libstdC++是線程安全的。如果分叉線程以外的線程在fork執行分叉進程時持有一個鎖,它將繼承當前鎖定狀態下的互斥鎖。新進程永遠不會看到這些互斥鎖解鎖。欲瞭解更多信息,請參閱man pthread_atfork

-2

我剛剛陷入了同樣的問題,最後發現 fork()重複了所有的線程。現在想象一下,什麼是你的程序進程後()與所有的線程上運行雙實例做...

以下規則是從"A Mini-guide regarding fork() and Pthreads"

1 - 你不想這樣做。如果你需要fork(),那麼: 只要有可能,fork()所有的 孩子在啓動任何線程之前。

編輯:試過,fork()的不重複線程。

+0

這是不正確的。 fork不會複製所有線程,它只會複製調用線程,如下所述:http://www.opengroup.org/onlinepubs/000095399/functions/fork.html – nos 2010-08-31 21:22:07

+0

我還沒有嘗試過,但我會做。 – ern0 2010-09-01 09:16:49

+0

嘗試並確認,fork()只能調用調用線程。 – ern0 2010-09-02 20:38:32