sigterm sigint sigkill 區別 .

http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html

我看網上應該有不少搜索這個區別的問題,但是回答的都不全面,其中sigterm與sigint尤其有一點區別比較重要,但大都沒有提及,今天我就遇到了這個問題,糾結了20分鐘才搞明白咋回事。

首先,對於說這幾個信號都是終止程序運行的說法不太準確,因爲程序收到信號後,如果不對信號處理,就會導致程序退出,但如果程序捕獲信號進行處理,按照它的邏輯,它是不一定會退出的。

在這三個信號中,sigkill是不能被捕獲的,程序收到這個信號後,一定會退出。這就是kill -9一定能保證將程序殺死的原因。

下面說一下sigterm與sigint的區別,其中有一點區別區別很多文章都沒有提及,也是我寫這篇blog的原因(如果人家都寫了,我就不用寫了唄)

信號 產生方式 對進程的影響
sigint 通過ctrl+c將會對當進程發送此信號 信號被當前進程樹接收到,也就是說,不僅當前進程會收到信號,它的子進程也會收到
sigterm kill命令不加參數就是發送這個信號 只有當前進程收到信號,子進程不會收到。如果當前進程被kill了,那麼它的子進程的父進程將會是init,也就是pid爲1的進程

下面這兩個代碼片段就能夠驗證這種情況(注意使用pcntl的時候,一定要declare ticks,要不然會杯具的發現函數沒有被調用,進程不退出,信號發過去沒有作用。php手冊竟然沒有強調這一點):

文件:loadhelper.php

01 #爲了pcntl能夠截獲信號
02 declare(ticks = 1);
03  
04 $arr_processes array();
05  
06 function terminate($signo){
07     echo "aaaaaaaaaaa/n";
08 }
09  
10 pcntl_signal(SIGTERM, "terminate", true);
11 pcntl_signal(SIGINT, "terminate", true);
12  
13 foreach($argv as $key => $operation){
14  
15     if(0 === $key){
16         continue;
17     }  
18  
19     $pipes array();
20     $process = proc_open($operationarray(), &$pipes);
21     if(false === $process){
22         exit(-1);
23     }
24     $arr_processes[] = $process;
25 }
26  
27 while(true){
28     sleep(100);
29 }

文件:child.php

01 declare(ticks=1);
02  
03 pcntl_signal(SIGINT, "terminate");
04 pcntl_signal(SIGTERM, "terminate");
05  
06 function terminate($signo){
07     echo "test_child/n";
08 }
09  
10 while(true){
11     sleep(100);
12 }

使用命令php loadhelper.php “php test.php”可以啓動這個測試。
1.輸入ctrl+c發送sigint可以看到,父進程與子進程的terminate都得到了執行,都有輸出,但父進程不會退出,因爲子進程還沒有退出
2.通過kill向父進程的pid發送sigterm,可以看到,只有父進程輸出

遺留問題:

父進程(loadhelper)接受到一次信號後,如果在terminate函數中調用exit,它還是不能退出的,因爲還有子進程沒有退出。但是從此以後它就不能再接收信號了(子進程還是能夠接收到sigint),可能是exit使進程進入了待回收狀態,具體還 需要後續在分析一把。

發佈了8 篇原創文章 · 獲贊 33 · 訪問量 65萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章