杀信号的例子 [英] kill signal example
问题描述
我想这个例子,我从了:的http:/ /www.cs.cf.ac.uk/Dave/C/node24.html :
I'm trying this example that I took from: http://www.cs.cf.ac.uk/Dave/C/node24.html:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();
main() {
int pid;
/* get child process */
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0) { /* child */
printf("\nI am the new child!\n\n");
signal(SIGHUP,sighup); /* set function calls */
signal(SIGINT,sigint);
signal(SIGQUIT, sigquit);
printf("\nChild going to loop...\n\n");
for(;;); /* loop for ever */
}
else /* parent */
{ /* pid hold id of child */
printf("\nPARENT: sending SIGHUP\n\n");
kill(pid,SIGHUP);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGINT\n\n");
kill(pid,SIGINT);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGQUIT\n\n");
kill(pid,SIGQUIT);
sleep(3);
}
}
void sighup() {
signal(SIGHUP,sighup); /* reset signal */
printf("CHILD: I have received a SIGHUP\n");
}
void sigint() {
signal(SIGINT,sigint); /* reset signal */
printf("CHILD: I have received a SIGINT\n");
}
void sigquit() {
printf("My DADDY has Killed me!!!\n");
exit(0);
}
但我没有看到子进程的任何输出。
But I do not see any output from the child process.
这是预期的行为?如果是这样;为什么?
Is it the expected behaviour? If so; why?
非常感谢你!
推荐答案
您code有一个主要的竞争条件。你不确保孩子完成调用信号
父发送信号之前。您可能需要使用某种同步原语,使家长等待孩子来安装处理程序,或者你需要分叉等孩子继承了他们之前安装信号处理程序。
Your code has a major race condition. You do not ensure that the child has finished calling signal
before the parent sends the signals. You either need to use some kind of synchronization primitive to make the parent wait for the child to install the handlers, or you need to install the signal handlers before forking so the child inherits them.
下面的<击>最简单罢>办法我知道同步这样的流程:
Here's the easiest way I know to synchronize processes like this:
- 分叉之前,调用
管(P)
以创建一个管道。 -
叉()
。 - 在父,
关闭(第[1]);
(书写端)和阅读(P [0],&安培;假,1);
- 在孩子,
关闭(P [0]);
和关闭(第[1]);
在安装信号处理程序后。 - 当从
父回报读
,可以确保孩子有安装了信号处理程序。您也可以关闭(P [0]);
在这一点父
- Before forking, call
pipe(p)
to create a pipe. fork()
.- In the parent,
close(p[1]);
(the writing end) andread(p[0], &dummy, 1);
- In the child,
close(p[0]);
andclose(p[1]);
after installing the signal handlers. - When the parent returns from
read
, you can be sure the child has setup its signal handlers. You can alsoclose(p[0]);
in the parent at this point.
编辑2:或许更好,更简单的方法:
Edit 2: Perhaps a better and easier approach:
- 分叉,呼叫
sigprocmask
来阻止所有信号,并保存旧信号面膜。 - 在父,通话
sigprocmask
再次右键分叉,恢复原始信号面具之后。 - 在孩子,通话
sigprocmask
安装信号处理程序以恢复原始信号面具之后。
- Before forking, call
sigprocmask
to block all signals and save the old signal mask. - In the parent, call
sigprocmask
again right after forking to restore the original signal mask. - In the child, call
sigprocmask
right after installing the signal handlers to restore the original signal mask.
这篇关于杀信号的例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!