我正在学习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()函数,但为什么它会调用信号处理程序?
答案 0 :(得分:2)
您正在向子进程发送信号17,因此会按预期调用其处理程序。
信号17是SIGCHLD
。当子进程终止时,SIGCHLD
被发送到父进程。当孩子退出时,将调用父母的处理程序。此信号不是来自父母;它来自操作系统,通知父母孩子的死亡。
答案 1 :(得分:0)
纠正过帐代码中的(大多数)错误后。
结果如下:
#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)