【问题标题】:Program goes infinite when catching fork using signal使用信号捕获 fork 时程序无限运行
【发布时间】:2013-03-13 06:36:33
【问题描述】:

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

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

输出是这样的: 你好世界 来到 Linux 来到 UNIX 来到 Linux 来到 UNIX 来到 Linux 来到 UNIX ...

又为什么来Linux打印一遍又一遍。

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

请帮忙。 谢谢。

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;
}

【问题讨论】:

    标签: linux unix operating-system signals fork


    【解决方案1】:

    它会进入无限循环不是很明显吗?您已经创建了一个 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 是否同步安全。即使进行上述更改避免了循环,程序仍然可能具有未定义的行为。 我猜 fork 是异步安全的

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 很多。但应该有一些理由。
      • 要弄清楚你必须看看你的操作系统中是如何实现分叉和信号的,这会有所不同,甚至可能在不同版本之间。我的猜测是,您的操作系统每次到达信号处理程序的末尾(在子进程中)都会再次调用信号处理程序。
      • 尝试在信号处理程序的子部分输出一些东西,这应该表明我是否正确。
      猜你喜欢
      • 2015-03-24
      • 2020-11-08
      • 1970-01-01
      • 2016-04-05
      • 2015-01-28
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      相关资源
      最近更新 更多