我學習在Linux中進程間通信,使用kill()將信號發送到熟睡的孩子process.Here是我的程序:爲什麼我的信號處理程序執行兩次?
8 void func(void);
9 int main(void){
10 int i, j;
11 pid_t status, retpid;
12 signal(17,func);
13 if(i = fork()){
14 printf("Parent:signal 17 will be sent to child!\n");
15 kill(i, 17);
16 wait(0);
17 printf("child process terminated\n");
18 }
19 else{
20 sleep(10);
21 printf("Child: A signal from my parent is received!\n");
22 exit(0);
23 }
24 }
25 void func(void)
26 {
27 printf("the signal has been sent!\n");
28 }
使用GCC編譯,程序產生異常結果,其中FUNC( )執行兩次:
./test4.out
Parent:signal 17 will be sent to child!
the signal has been sent!
Child: A signal from my parent is received!
the signal has been sent!
child process terminated
我分析的結果,然後刪除以下兩個行:
16 wait(0);
17 printf("child process terminated\n");
和結果b ecame正常,用func()只調用一次。看起來罪魁禍首是wait()函數,但爲什麼它會調用一個信號處理程序?
**可能**當父進程關閉時,它正在等待進程收割者的KILL信號...?一個過程完成後,它不會真的死去。它一直持續到「raper」(無論是所有者還是負責收割殭屍進程的系統進程)都已完成......它可能是收割者信號表明它已完成。 – Myst
'printf'不是一個信號安全函數,不應該在信號處理程序中調用。可能的解釋是它導致了未定義的行爲(例如,兩次刷新粗壯的緩衝區 - 一次在信號處理程序中,一次在進程退出時)。 – kaylum
請發佈文本代碼,不要與前綴行號碼。我們不能只抓取發佈的代碼並將其粘貼到我們的編輯器中,而無需進行大量逐行編輯。不要使用製表符縮進,因爲每個文字處理器/編輯器都有爲各個偏好設置的製表位/製表符寬度。即使修復了行號問題,發佈的代碼也不會編譯。它似乎缺少所需的'#include'語句 – user3629249