当前位置: 技术问答>linux和unix
请教关于Kill向子进程发送信号的问题,子进程如何相应信号,为什么子进程接受不到。
来源: 互联网 发布时间:2015-12-16
本文导语: 一个上机题目说,一个父进程创建两个子进程,父进程相应ctrl+c信号后,向两个子进程发送信号,子进程接收到信号后,分别打印一条输出语句,然后输出。 我写的程序,除了用SIGKILL和SIGSTOP信号,子进程可以收到,...
一个上机题目说,一个父进程创建两个子进程,父进程相应ctrl+c信号后,向两个子进程发送信号,子进程接收到信号后,分别打印一条输出语句,然后输出。
我写的程序,除了用SIGKILL和SIGSTOP信号,子进程可以收到,别的信号子进程收不到。但是SIGKILL和SIGSTOP收到后,不会去执行我注册的处理函数,直接就是退出或者停止,这是为什么,下面是我写的程序。
#include
#include
#include
#include
pid_t tchild1 = 0,tchild2 = 0;
void killchild()
{
printf("Kill Child Proc %x %xn",tchild1,tchild2);
kill(tchild1,SIGKILL);
kill(tchild2,SIGKILL);
}
void child1()
{
printf("Child1 is killed by parentn");
exit(0);
}
void child2()
{
printf("Child2 is killed by parentn");
exit(0);
}
main()
{
int i;
tchild1 = fork(); //create the first process
if(tchild1 == -1)
{
printf("Create New Process Failedn");
}
else if(tchild1 == 0)
{
//the first child process
printf("This New Process Created by PID %xn",getppid());
signal(SIGKILL,child1);
while(1);
}
else
{
printf("Create New Process Successful!New PID %xn",tchild1);
tchild2 = fork(); //create the second process
if(tchild2 == -1)
{
printf("Create New Process2 Failedn");
}
else if(tchild2 == 0)
{
//the second child process
printf("This New Process2 Created by PID %xn",getppid());
signal(SIGKILL,child2);
while(1);
}
else
{
printf("Create New Process2 Successful!New PID %xn",tchild2);
signal(SIGINT,killchild);
wait();
printf("child kill okn");
}
}
}
我写的程序,除了用SIGKILL和SIGSTOP信号,子进程可以收到,别的信号子进程收不到。但是SIGKILL和SIGSTOP收到后,不会去执行我注册的处理函数,直接就是退出或者停止,这是为什么,下面是我写的程序。
#include
#include
#include
#include
pid_t tchild1 = 0,tchild2 = 0;
void killchild()
{
printf("Kill Child Proc %x %xn",tchild1,tchild2);
kill(tchild1,SIGKILL);
kill(tchild2,SIGKILL);
}
void child1()
{
printf("Child1 is killed by parentn");
exit(0);
}
void child2()
{
printf("Child2 is killed by parentn");
exit(0);
}
main()
{
int i;
tchild1 = fork(); //create the first process
if(tchild1 == -1)
{
printf("Create New Process Failedn");
}
else if(tchild1 == 0)
{
//the first child process
printf("This New Process Created by PID %xn",getppid());
signal(SIGKILL,child1);
while(1);
}
else
{
printf("Create New Process Successful!New PID %xn",tchild1);
tchild2 = fork(); //create the second process
if(tchild2 == -1)
{
printf("Create New Process2 Failedn");
}
else if(tchild2 == 0)
{
//the second child process
printf("This New Process2 Created by PID %xn",getppid());
signal(SIGKILL,child2);
while(1);
}
else
{
printf("Create New Process2 Successful!New PID %xn",tchild2);
signal(SIGINT,killchild);
wait();
printf("child kill okn");
}
}
}
|
理论上没问题,但中间的细节很复杂,我给找出两点,你对信号的用法有点毛病。
1.用signal函数不好,它不是可移植的(在不同的平台有不同的语义,像restart特性),用sigaction代替。
2.信号处理函数应该尽可能的精简,绝对不要调用C io库(比如printf)或系统调用(比如exit)。原因很简单,
a) 当信号到达,系统会中止当前进程代码执行,转入信号处理函数,这时进程本来可能正处在非常脆弱的阶段,比如指令执行中间。长时的io调用和系统调用会引起不可恢复的数据错误。
b) 信号处理函数本身可能被其他的信号中断,而且被信号中断是不可恢复的。除非你屏蔽了该信号。长时的io调用和系统调用增加了被中断的可能性。
所以一般在信号处理函数中都只应该做能够让你知道有信号发生这么一件事就行了,比如为一个原子化变量赋值 flag=1; (flag为全局 sig_atomic型)
*nix信号实现都是这样的,如果你想移植,最好按标准的办法来(也许现代OS像linux可以处理上面的问题,但我不能确定)。
你的这个具体问题表面上看没有问题,但由于while(1);会疯狂掠夺CPU时间片,再加上你使用了不可靠的信号处理方式,导致整个程序运行结果都不可预期(可能性太多)。
如果你把 while(1);行改为 while(1) usleep(200); 好像是可以的。
1.用signal函数不好,它不是可移植的(在不同的平台有不同的语义,像restart特性),用sigaction代替。
2.信号处理函数应该尽可能的精简,绝对不要调用C io库(比如printf)或系统调用(比如exit)。原因很简单,
a) 当信号到达,系统会中止当前进程代码执行,转入信号处理函数,这时进程本来可能正处在非常脆弱的阶段,比如指令执行中间。长时的io调用和系统调用会引起不可恢复的数据错误。
b) 信号处理函数本身可能被其他的信号中断,而且被信号中断是不可恢复的。除非你屏蔽了该信号。长时的io调用和系统调用增加了被中断的可能性。
所以一般在信号处理函数中都只应该做能够让你知道有信号发生这么一件事就行了,比如为一个原子化变量赋值 flag=1; (flag为全局 sig_atomic型)
*nix信号实现都是这样的,如果你想移植,最好按标准的办法来(也许现代OS像linux可以处理上面的问题,但我不能确定)。
你的这个具体问题表面上看没有问题,但由于while(1);会疯狂掠夺CPU时间片,再加上你使用了不可靠的信号处理方式,导致整个程序运行结果都不可预期(可能性太多)。
如果你把 while(1);行改为 while(1) usleep(200); 好像是可以的。
|
但是SIGKILL和SIGSTOP收到后,不会去执行我注册的处理函数,直接就是退出或者停止,这是为什么
===========================
SIGKILL , SIGSTOP不能被捕获
===========================
SIGKILL , SIGSTOP不能被捕获
|
SIGKILL 和 SIGSTOP 是不能被捕获和忽略的
|
SIGUSR1和SIGUSR2是怎么定义的???
|
我试了一下,把
kill(tchild1,SIGUSR1);
kill(tchild2,SIGUSR2);
放到主进程里,就可以.放到信号处理函数里就不行.还不知道为什么.
你的信号处理函数的原型应该是这样:
void sig_handle(int signo);
kill(tchild1,SIGUSR1);
kill(tchild2,SIGUSR2);
放到主进程里,就可以.放到信号处理函数里就不行.还不知道为什么.
你的信号处理函数的原型应该是这样:
void sig_handle(int signo);
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。