如何等待子进程发送信号?

Posted

技术标签:

【中文标题】如何等待子进程发送信号?【英文标题】:How to wait for the children processes to send signals? 【发布时间】:2015-05-03 13:47:19 【问题描述】:
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

void handler(int signumber)

    return;


int main()

    int i, pid;
    int children_count = 5;
    int arr_childprocesses[5];
    int parent_pid = getpid();

    for(i=0;i<children_count;i++)
    
        pid = fork();
        if(pid == -1) 
        
            perror("Err");
            exit(EXIT_FAILURE);
        

        if(pid == 0) break;

        arr_childprocesses[i] = pid;
    

    if (pid == 0) // children
    
        kill(parent_pid,SIGUSR1);
        printf("Child(%d) sig sent. Waiting 5s...\n",getpid());
        sleep(5);
        printf("Child(%d) terminated.\n",getpid());
    
    else // parent
    
        signal(SIGUSR1,handler);
        for(i=0;i<children_count;++i)
        
            waitpid(arr_childprocesses[i],NULL,0);
            printf("Parent: Signal received.\n");
        
        printf("Parent(%d) signals received. Waiting 3s...\n",getpid());
        sleep(3);
        printf("Parent(%d) terminated.\n",getpid());
    

    exit(EXIT_SUCCESS); 

我想等到所有孩子都给我发信号。然后与孩子和父母一起做一些工作。但是程序会停止,直到所有孩子都终止。我该怎么做?

结果:

更新 1:包含完整代码和结果

【问题讨论】:

waitpid() 不等待来自孩子的信号,而是等待孩子的状态变化,即结束、停止或(重新)开始。然而,这些状态的变化伴随着一个信号。 啊,你是对的。我认为我应该使用不同的逻辑,比如在信号处理程序中增加一个全局 int 计数器。并使用类似这样的东西而不是 waitpid(): while(counter 【参考方案1】:

您可能在这里面临一场比赛。

父级在设置此信号的处理程序之前收到SIGUSR1。由于接收SIGUSR1 时的默认行为是结束,因此父级死亡。

您希望在 分叉子代之前在父代中设置信号处理程序。

(如果从程序设计中不接受孩子设置SIGUSR1 信号处理程序,只需调用signal(SIGUSR1, SIG_DFL) 作为孩子内部的第一条语句来卸载此处理程序。)

为了证明这个理论,您可能希望暂时在调用 kill() 之前的子项中添加一个 sleep(1);


作为完成任务的提示:

看看sigaction(),因为它提供了比signal() 功能更强大的信号接口。尤其要阅读SA_SIGINFO 标志,因为它可以将siginfo_t 类型变量传递给信号处理程序。后一个变量携带有关谁(由 PID 标识)发送信号的信息,这是解决方案的关键。

【讨论】:

感谢您的回答,但没有帮助。我也包含了我的完整示例和结果。你能检查一下吗? @BlackCat:好的,但比赛还在进行中。

以上是关于如何等待子进程发送信号?的主要内容,如果未能解决你的问题,请参考以下文章

如何让子进程等待信号?

如何在不丢失信号的情况下将信号从多个子进程发送到主进程?

php如何把自身进程设置为系统进程

如何让子进程等待其兄弟?

捕获信号时如何正确等待bash子进程完成

fork 和 signal:如何将信号从父进程发送到特定的子进程