gpt4 book ai didi

linux - 使用信号捕获 fork 时程序变得无限

转载 作者:太空狗 更新时间:2023-10-29 12:34:30 30 4
gpt4 key购买 nike

大家好,在使用 fork 和 signal 做一些实验时,我遇到了一个显示非常有趣的行为的程序,但经过几个小时的努力,我无法弄清楚发生了什么。

我想做的是在主体内创建一个子进程,然后打印“hello world”,然后调用退出。在此之后,完全可以理解它的信号处理程序将被调用,并且被 wait 系统调用阻塞的父进程也将被调用。现在我正在信号处理程序中创建另一个进程,但从那里开始,输出变为无限。

输出是这样的: Hello World 来到 Linux 来到 UNIX 来到 Linux 来到 UNIX 来到 Linux 来到 UNIX ...

还有为什么一而再再而三的来到Linux打印。

另外请告诉我什么时候 fork 被调用,我知道重复的地址空间是由父进程组成的,但是信号处理程序呢?他们也会重复吗?在我的例子中,当 child 调用退出时。然后被调用的信号处理程序是子级或父级的。

请帮忙。谢谢。

void sig_handler(int signo)
{
if(fork() == 0){

}
else{
int pid = 0;
wait(&pid);
printf("Come to unix");
fflush(stdout);
}
}


int main()
{
if (signal(SIGCHLD, sig_handler) == SIG_ERR){
}

int child_pid;
int i;

child_pid = fork();
switch (child_pid) {
case -1:
perror("fork");
exit(1);
case 0:
printf("hello world\n");fflush(stdout);
exit(0);
default:
wait(&i);
printf("Come to linux");
exit(0);
//break;
}

return 0;
}

最佳答案

不是很明显会进入死循环吗?您已经创建了一个 SIGCHLD 处理程序,然后在该处理程序中再次 fork 并等待子进程退出。基本上,当该处理程序中的子项退出时,父项再次进入处理程序。下面的代码应该避免它。在信号处理程序的开始,通过将其设置为默认值来避免信号。

void sig_handler(int signo) {
signal (SIGCHLD, SIG_IGN);
if(fork() == 0){

}
else{
int pid = 0;
wait(&pid);
printf("Come to unix");
fflush(stdout);
}
}

此外,您只能在信号处理程序中调用异步信号安全例程以避免未定义的行为。我不确定 printf 和 fflush 是否同步安全。即使进行上述更改避免了循环,程序仍可能具有未定义的行为。我猜 fork 是异步安全的

请参阅以下可能有帮助的讨论: http://sourceware.org/bugzilla/show_bug.cgi?id=4737

关于linux - 使用信号捕获 fork 时程序变得无限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15586703/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com