如何等待子进程发送信号? [英] How to wait for the children processes to send signals?

查看:93
本文介绍了如何等待子进程发送信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

I want to wait until all the children send me a signal. Then do some work with the children and with the parent too. But the program stops until all the children terminate. How should I do this?

结果:

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

Update 1: full code plus result included

推荐答案

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

You are probably facing a race here.

父级在设置此信号的处理程序之前会收到SIGUSR1.由于接收SIGUSR1的默认行为即将结束,因此父代会死亡.

The parent receives the SIGUSR1 before its handler for this signal had been set up. As the default behaviour on receiving a SIGUSR1 is to end, the parent dies.

您要分支孩子之前,在父母内部设置信号处理程序.

You want to setup the signal handler inside the parent before forking off the child.

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

(If from the programs design it is unacceptbale for the child to have SIGUSR1 signal handler set up, just call signal(SIGUSR1, SIG_DFL) as the 1st statement inside the child to deinstall this handler.)

为证明这一理论,您可能希望在调用kill()之前,在孩子内部临时添加一个sleep(1);.

To prove this theory you might like to temporarily add a sleep(1); inside the child just before the call to kill().

作为完成任务的提示:

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

Have a look at sigaction() as it provides a much more powerful interface to signalling then the function signal() does. Especially read about the SA_SIGINFO flag as it enables passing a siginfo_t typed variable to your signal handler. This latter variable carries info on who (identified by PID) sent the signal, which is the key to your solution.

这篇关于如何等待子进程发送信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆