当使用信号捕捉叉时程序变得无限

嗨,每一个,而做一些实验使用叉子和信号,我遇到了一个程序,显示非常有趣的行为,但经过数小时的努力,我无法弄清楚发生了什么事情。

我想要做的是我在主体内创build一个subprocess,然后打印“你好世界”,然后调用退出。 在这之后,我们完全明白它的信号处理程序会被调用,并且等待系统调用阻塞的父进程也会被调用。 现在我正在信号处理程序中创build另一个进程,但是从那里开始,输出变得无限。

输出是这样的:Hello world来到Linux来到UNIX来到Linux来到UNIX来到Linux来到UNIX来…

另外为什么来到Linux打印一遍又一遍。

也请告诉我什么时候拨叫,我知道重复的地址空间是由父母,但信号处理程序呢? 他们也得到重复吗? 在我的情况下,当小孩叫退出。 然后被调用的信号处理程序是孩子或父母。

请帮忙。 谢谢。

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处理程序,然后在该处理程序中再次分叉并等待该子节点退出。 基本上,当处理程序中的孩子退出时,父母再次进入处理程序。 下面的代码应该避免它。 在信号处理程序的开始处,通过将其设置为默认值来避免信号。

 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是否同步安全。 即使做出上述改变避免了循环,程序仍然可能具有未定义的行为。 我猜叉是异步安全的

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

在信号处理程序中调用fork(2)根据POSIX标准有未定义的行为,所以不要这样做:)

请参阅: http : //pubs.opengroup.org/onlinepubs/009695399/functions/fork.html 。