如何在进程之间发送信号?

时间:2019-01-10 00:56:10

标签: c signals

所以,我想在进程之间发送信号。

我要发送一个从child1开始的信号,由父进程捕获,然后,将相同的信号发送给子进程2。当孩子2接收到该信号时,我想向父子进程发送另一个信号,然后亲子杀死了两个子进程。

我已经尝试过了:

new_pid = fork();
                        sleep(3);
                        switch(new_pid) {
                        case -1:
                                perror("fork failed");
                                exit(1);
                        case 0:
                                kill(getppid(), SIGUSR1);
                                sleep(3);
                                pause();
                                break;
                        default:
                                signal(SIGUSR1, trata_SIGSEGV);
                                sleep(3);
                                new_pid2 = fork();
                                sleep(3);
                                kill(new_pid2, SIGUSR1);
                                sleep(3);
                                switch(new_pid2) {
                                case -1:
                                        perror("fork failed");
                                case 0:
                                        signal(SIGUSR1, trata_SIGSEGV);
                                        kill(getppid(), SIGUSR2);
                                        sleep(3);
                                        pause();
                                        break;
                                default:
                                        signal(SIGUSR2, trata_SIGSEGV);
                                        kill(new_pid, SIGKILL);
                                        kill(new_pid2, SIGKILL);
                                        break;
                                }
                                break;

只有父母的孩子收到信号,然后什么也没有发生,然后进入程序菜单。

   void trata_SIGSEGV(int sig){

        if (sig == SIGUSR1) {
                printf("Received");
        }

        if (sig == SIGUSR2) {
                printf("Received");
        }

        if (sig == SIGINT) {
                printf("Received");
        }
}

1 个答案:

答案 0 :(得分:1)

这里有几个问题。 trata_SIGSEGV中可能还有更多。

  1. 您在分叉之后没有时间将流程设置为可以进行处理了。当您发送默认终止信号时,可能是收件人在收件人监听它们之前杀死了收件人。 (您是否认为信号正在等待信号?不是吗;它只是配置如果/何时发生信号应该执行的操作。)
  2. 第19行正在尝试发送trata_SIGSEGV信号来处理SIGUSR2。那是行不通的。
  3. 您最终遇到的问题是-主执行线程在处理过程中没有任何延迟,从分叉进程到告诉调度程序简单结束它们。

在现代计算机上,甚至一毫秒的延迟也可能远远超过用于设置信号处理程序的时间。但是,如果希望它们可靠地发生,则需要给其他进程至少一些延迟,以使它们到达所需的位置。

或者,我认为您可以在父级中设置信号处理程序,然后进行分叉。

鉴于您的更新,我想知道您如何知道哪个进程发出了什么信号。我对您的信号处理程序的建议:

void trata_SIGSEGV(int sig) {
    printf("%d received signal %d\n", getpid(), sig);
    if (SIGINT == sig) exit(1);
}

此外,我注意到您在检查派生返回值之前向进程2发送了第一个信号,因此进程2在可能设置信号处理程序之前向自身发出了信号。在进行任何分叉之前,请先设置信号处理程序,这样就不会出现种族问题。我已经在对您的代码的测试中验证了信号处理程序会在fork中保留。