2011-08-03 79 views
3

有一個擁有兩個線程守護程序:TH1,TH2。 th2使用read(2)讀取套接字。處理兩個結果SIGTERMs

如果我殺死守護進程SIGTERM,th1捕獲並處理信號(設置終止標誌),之後守護進程析構函數被調用,它調用pthread_kill(th2, SIGTERM)。然而,第二個線程不接收SIGTERM,因此它不會被殺(當套接字接收數據,並從read()失控,它執行完畢,作爲終止標誌已設置)。

如果我打電話pthread_kill(th2, SIGUSR2),然後pthread_kill(th2, SIGTERM),一切都正確完成。因此,UNIX似乎不允許發送相同的信號。

難道這種行爲取決於操作系統?我們能否確保指定的線程從另一個線程接收到SIGTERM

+1

如果包括適當的編程語言的標籤,C,C++,或yourLanguageHere你會得到更多的「眼睛」上你的問題。祝你好運。 – shellter

+2

謝謝,添加了標籤。我認爲unix的意思是C) – vissi

+2

@vissi:這是錯誤的。您應該只包含您工作語言的標籤。除非你的問題涉及互操作性,否則你只能標記一種語言。 – Puppy

回答

5

的Unix並允許發送多個連續信號的處理,但如果該信號被髮送靠得太近,或一個附加的信號被被送到一個已經未決信號交付之前的過程中,則多個信號可以被連接成一個單一的信號事件。

還要記住的是,雖然pthread_kill()將信號發送到一個給定的線程中處理,所述信號的實際處理具有全局效果(即,信號處理程序是每個進程,而不是每線程)。

您可能還需要尋找到顯式調用pthread_cancel()因爲read()是一個有效的取消點。如果需要,您可以添加取消處理程序,並且如果您使用的功能不是取消安全的,則可以阻止線程的取消狀態。您可以閱讀關於使用pthread_cancel()here的一些提示。

+0

'sigaction()'和SA_SIGINFO與POSIX實時信號排隊行爲非常正交 - 說他們「啓用」實時語義是不準確的。此外,誤導性地建議可以在運行時啓用這些語義。實時信號(SIGRTMIN .. SIGRTMAX)總是排隊,而標準信號不會。 (該規範允許他們,但在實踐中,他們不這樣做) – pilcrow

+0

好的,這就是我的困惑......從規格出發(而不是像Linux中所實現的那樣),似乎是標準的如果您使用'sigaction()'爲標準信號類型設置SA_SIGINFO,那麼除了實時信號之外,信號也會排隊。感謝您澄清這一點...我會更新我的答案。 – Jason

1

一個比較老派,但有效的方法是使用select()和管道重新調度信號的所有線程。 (你在阻塞句柄上選擇()管道讀取句柄)。