Unix和信号处理程序(C)
我是一名学生,我正在努力理解Unix编程课程中的信号 首先,我想测试一个简单的例子:一个进程生成一个子进程,需要对实际创建进行确认。 我用叉子叉着,在孩子的肚子里,我给父亲发了一个信号 kill(getppid(),SIGUSR1); 然后,在父亲的心里,我写了一个停顿();sys调用来阻止进程,直到收到信号,然后我编写了 (sigaction(SIGUSR1,&sa,NULL)检查 问题是,信号被发送,程序停止,没有处理程序执行 我用Unix和信号处理程序(C),c,unix,concurrency,C,Unix,Concurrency,我是一名学生,我正在努力理解Unix编程课程中的信号 首先,我想测试一个简单的例子:一个进程生成一个子进程,需要对实际创建进行确认。 我用叉子叉着,在孩子的肚子里,我给父亲发了一个信号 kill(getppid(),SIGUSR1); 然后,在父亲的心里,我写了一个停顿();sys调用来阻止进程,直到收到信号,然后我编写了 (sigaction(SIGUSR1,&sa,NULL)检查 问题是,信号被发送,程序停止,没有处理程序执行 我用 $gcc -Wall -o test test.c 我没
$gcc -Wall -o test test.c
我没有收到任何警告,输出是
$I am the father
$I am the child
$User defined signal 1
我知道我可以用其他的方法来实现这一点(使用sleepsys调用等),但我只想了解为什么这段代码不起作用
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void new_child (int sig){
write(1,"I made a new child\n",50);
}
int main(){
pid_t child;
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = new_child;
switch(child = fork()){
case -1:
printf("Error.\n");
exit(EXIT_FAILURE);
case 0:
printf("I am the child\n");
kill(getppid(), SIGUSR1);
break;
default:
printf("I am the father\n");
pause();
if (sigaction(SIGUSR1, &sa, NULL) == -1){
printf("Signal error.\n");
exit(EXIT_FAILURE);
}
printf("I'm done.");
kill (child, SIGKILL);
exit(EXIT_SUCCESS);
}
}
#包括
#包括
#包括
#包括
无效新子项(int sig){
写(1,“我生了一个新孩子”,50);
}
int main(){
pid_t儿童;
struct-sigaction-sa;
sigemptyset(和sa.sa_面具);
sa.sa_标志=0;
sa.sa_handler=新的_子项;
开关(child=fork()){
案例1:
printf(“错误。\n”);
退出(退出失败);
案例0:
printf(“我是孩子”\n);
kill(getppid(),SIGUSR1);
打破
违约:
printf(“我是父亲”);
暂停();
if(sigaction(SIGUSR1,&sa,NULL)=-1){
printf(“信号错误。\n”);
退出(退出失败);
}
printf(“我做完了。”);
杀死(孩子,SIGKILL);
退出(退出成功);
}
}
我知道已经有人问过这个问题,但我似乎找不到一个适合我的解决方案。您必须更改代码开头的信号,以便在收到SIGUSR后立即执行–Anjaneyulu
“必须在代码开头更改信号…”此限制有点严格。在调用
fork()
之前,需要安装最新的信号处理程序。
–alk您必须更改代码开头的信号,以便在收到SIGUSR后立即执行。非常感谢。这确实有效!我发现sys call pause()非常有用,但我的书中甚至没有它的使用示例。
编写(1,“我生了一个新孩子”\n“,50);
将向文件描述符1写入大量垃圾,因为的“我生了一个新孩子”
的长度远远小于50。这是技术上未定义的行为,可能会导致程序失败。@Anjaneyulu:“您必须更改代码开头的信号…”这个限制有点紧。在调用fork()
@alk-yest信号处理程序而不是信号之前,需要安装最新的信号处理程序