C语言 终止信号示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6287167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
kill signal example
提问by Christian Wagner
I'm trying this example that I took from: http://www.cs.cf.ac.uk/Dave/C/node24.html:
我正在尝试从以下示例中获取的示例: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?
这是预期的行为吗?如果是这样的话; 为什么?
Thank you very much!
非常感谢!
回答by R.. GitHub STOP HELPING ICE
Your code has a major race condition. You do not ensure that the child has finished calling signalbefore 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.
你的代码有一个主要的竞争条件。signal在父级发送信号之前,您不能确保子级已完成调用。您要么需要使用某种同步原语让父进程等待子进程安装处理程序,要么需要在分叉之前安装信号处理程序,以便子进程继承它们。
Here's the easiestway I know to synchronize processes like this:
这是我所知道的同步流程的最简单方法:
- 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.
- 在 fork 之前,调用
pipe(p)以创建管道。 fork().- 在父级中,
close(p[1]);(写作结束)和read(p[0], &dummy, 1); - 在孩子中,
close(p[0]);并close(p[1]);在安装信号处理程序之后。 - 当父级从 返回时
read,您可以确定子级已设置其信号处理程序。此时您也可以close(p[0]);在父级中。
Edit 2:Perhaps a better and easier approach:
编辑 2:也许更好更简单的方法:
- Before forking, call
sigprocmaskto block all signals and save the old signal mask. - In the parent, call
sigprocmaskagain right after forking to restore the original signal mask. - In the child, call
sigprocmaskright after installing the signal handlers to restore the original signal mask.
- 在分叉之前,调用
sigprocmask阻塞所有信号并保存旧的信号掩码。 - 在父级中,
sigprocmask分叉后立即再次调用以恢复原始信号掩码。 - 在子进程中,
sigprocmask安装信号处理程序后立即调用以恢复原始信号掩码。
回答by gkslsahin
You should use getpid() instead of pid().
您应该使用 getpid() 而不是 pid()。

