2010-04-24 25 views
0

好了,如果我在Linux上的子線程運行(使用並行線程,如果該事項),我運行以下命令在下一個語句之前是否會發送一個信號,並保證處理父線程?

kill(getpid(), someSignal); 

它將給定信號發送到當前線程的父。

我的問題:如果在運行kill()之後的語句之前,它是否能夠保證父節點立即得到CPU並處理信號(如果是SIGKILL或者如果是其他信號則會殺死該應用)或者是否有可能 - 甚至很有可能 - 在子線程處理信號之前,將會運行以下任何命令kill()

+3

該行實際上並未將信號發送到「當前線程的父級」 - 它將其發送到當前*進程*,這意味着該進程的任何線程都可以接收信號沒有信號被阻塞 - 包括你正在調用'kill()'的線程。 – caf 2010-04-24 02:58:34

+0

@caf嗯,這些線程在技術上是他們自己的進程在linux中與他們自己的pid,所以這確實使事情變得複雜。但你仍然可以是對的。我並不是很瞭解信號的處理方式 - 特別是在線程方面。但學習仍在繼續...... – 2010-04-24 03:15:53

+1

Linux中的pthreads符合POSIX線程標準(因此爲「pthreads」)。即使線程是在內核中使用單獨的'task_struct'實現的,進程和線程之間也有區別。結果是'getpid()'將在進程中的每個線程(POSIX「進程ID」)中返回相同的值,而'gettid()'(glibc不提供包裝)返回個別線程。 – caf 2010-04-24 05:16:09

回答

3

信號異步傳遞,所以你不能指望線程處理它們立即處理它們;此外,它將不得不做一些工作來處理它。

如果一個sigprocmask()調用屏蔽了所有線程中的信號,那麼信號只有在未被屏蔽後纔會被執行。

信號不會轉到任何特定的線程,除非您使用sigprocmask將它們從您不希望獲得它們的線程中屏蔽掉。大多數多線程程序都這樣做,因爲將進程級別的信號傳遞到任意線程通常不是您想要的。

5

不,不能保證。通常,除非使用顯式同步機制(例如,phtread_mutex或信號量),否則不能對發生在單獨線程(或進程)中的事件發生的時間做出任何假設。

對於多CPU(或多核)系統來說,尤其如此,其中多個線程可以在單獨的CPU上同時運行,但即使在單CPU系統上也無法保證。

1

發送到進程(線程組)的信號通常可能會傳送到任何線程,並且您通常不能保證在kill調用返回之前處理程序將完成。

如果您在多線程進程中運行

kill(getpid(), someSignal); 

,那麼你只能是確保您的sighandler將之前在一個非常特殊的情形,其中 所有,但調用線程具有someSignal阻塞kill返回運行(在在這種情況下,sig處理程序將從調用kill的線程運行)。

參見 http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html

如果SIG爲發送 過程中產生的PID原因值,如果不阻止的簽名被調用線程並且如果沒有 其他線程已SIG的暢通或在sigwait()函數 中等待sig,或者sig或者至少一個未處理的未阻止信號在kill()返回之前傳遞給發送線程的 。

相關問題