は私が子供process.Here睡眠に信号を送信するためにキル()を使用して、Linuxでのプロセス間通信を勉強することは私のプログラムです:gccでコンパイルさ私のシグナルハンドラがなぜ2回実行されるのですか?
が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 }
、プログラムが異常な結果を生じ、これFUNC(中)2回実行:
./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
私は結果を分析し、その後、次の2行を削除:
16 wait(0);
17 printf("child process terminated\n");
そして結果bをfunc()は一度だけ呼び出されます。原因はwait()関数だと思われますが、なぜシグナルハンドラを呼び出すのですか?投稿コードのエラー(ほとんど)を補正した後
**おそらく**親プロセスがプロセスリーパーからのKILL信号を待っているときに...?プロセスが終了すると、実際には終了しません。それは "ラッパー"(ゾンビプロセスを受け持っている所有者かシステムプロセスのいずれか)が終了するまで続きます...それが完了したことを通知する刈り手かもしれません。 – Myst
'printf'はシグナルセーフな関数ではなく、シグナルハンドラで呼び出されるべきではありません。可能性のある説明は、未定義の振る舞いを引き起こしているということです(例えば、シグナルハンドラで1回、プロセスが終了したときに1回、スタウトバッファを2回フラッシュします)。 – kaylum
テキストコードを記入してください。先頭に行番号を付けないでください。投稿されたコードをつかまえて編集者に貼り付けることはできません。行ごとにたくさん編集する必要はありません。各ワードプロセッサ/エディタには、個々の環境設定のタブストップ/タブ幅が設定されているため、インデント用にタブを使用しないでください。行番号の問題を修正した後でも、投稿されたコードはコンパイルされません。必要な '#include'ステートメント – user3629249