[英]Why my signal handler executes twice?
我正在學習Linux中的進程間通信,使用kill()向正在休眠的子進程發送信號,這是我的程序:
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");
結果變為正常,僅調用一次func()。 罪魁禍首似乎是wait()函數,但是為什么會調用信號處理程序呢?
您正在向子進程發送信號17,因此將按預期調用其處理程序。
信號17是SIGCHLD
。 當子進程死亡時, SIGCHLD
被發送到父進程。 子項退出時,將調用父項的處理程序。 這個信號不是來自父母的。 它來自操作系統,用於通知父母孩子的死亡。
更正(大多數)已發布代碼中的錯誤之后。
結果是以下代碼:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
void func( int );
int main(void)
{
pid_t i;
//pid_t status;
//pid_t retpid;
signal(17,func);
if( (i = fork()) )
{
printf( "the fork'd child pid:%d\n", i );
printf("Parent:signal 17 will be sent to child!\n");
kill(i, 17);
wait(NULL);
printf("child process terminated\n");
}
else
{
sleep(10);
printf("Child: pid:%d\n", getpid());
exit(0);
}
}
void func( int theSignal)
{
if( 17 == theSignal )
{
fprintf( stdout, "the 17 signal has been processed by %d!\n", getpid());
}
else
{
fprintf( stdout, "the %d signal is processed\n", theSignal );
}
}
輸出為:
the fork'd child pid:4845
Parent:signal 17 will be sent to child!
the 17 signal has been processed by 4845!
Child: pid:4845
the 17 signal has been processed by 4844!
child process terminated
這清楚地表明父母和孩子都在處理信號
編輯:
但是,當使用唯一的SIGUSR2值時,如以下代碼所示:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
void func( int );
#define MY_SIGNAL (31)
int main(void)
{
pid_t i;
//pid_t status;
//pid_t retpid;
signal(17,func);
signal(31,func);
if( (i = fork()) )
{
printf( "the fork'd child pid:%d\n", i );
printf("Parent:signal %d will be sent to child!\n", MY_SIGNAL);
kill(i, MY_SIGNAL);
wait(NULL);
printf("child process terminated\n");
}
else
{
sleep(10);
printf("Child: pid:%d\n", getpid());
exit(0);
}
}
void func( int theSignal)
{
if( MY_SIGNAL == theSignal )
{
printf("the %d signal has been processed by %d!\n", MY_SIGNAL, getpid());
}
else
{
printf( "the %d signal is processed\n", theSignal );
}
}
那么輸出是:
the fork'd child pid:5099
Parent:signal 31 will be sent to child!
the 31 signal has been processed by 5099!
Child: pid:5099
the 17 signal is processed
child process terminated
清楚地顯示了子處理信號31(SIGUSR2)和父處理信號17(SIGCHLD)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.