首页 > 解决方案 > How to sync two process (child and parent) with signals in C?

问题描述

I want use signal (SIGUSR1) to sync process in C. I want that parent process wainting for a signal, when receive this signal, send the same signal to child process. I wrote a short paragraph to stimulate reasoning, but it does not go away.

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>



void trataSIGUSR1(int sigNum) {
    printf("SIGUSR1\n");
}

int main(void) {

    pid_t pid;
    struct sigaction sa;

    pid = fork();

    if (pid == 0) {
        struct sigaction sa = {0};
        sa.sa_handler = trataSIGUSR1;
        sa.sa_flags = 0;
        sigemptyset(&sa.sa_mask);
        sigaction(SIGUSR1,&sa,NULL);
        pause();
        printf("This never execute");
    } else {
        printf("I'am father: %d!\n",getppid());
        kill(0,SIGUSR1);
        pause();
    }
}

OUTPUT

I'am father: 12082!
User defined signal 1: 30

标签: cprocesssignals

解决方案


使用简单提示pause()kill()pause()用于阻止进程执行直到收到任何信号,一旦收到信号,然后do_something()用于kill()发送SIGUSR1信号。

此外,当您使用 时pause(),它会暂停进程,直到收到任何信号,并且对于该信号,默认操作应该是用户定义的 ISR。从手册页pause()

RETURN VALUE pause()仅在 asignal was caught和 返回时signal-catching function 返回。在这种情况下 pause() 返回 -1,并且 errno 设置为 EINTR。

这是示例所需的示例代码

//int nSIGINT = 0; /* declare variable of type volatile sigatomic_t  */
volatile sigatomic_t nSIGINT;
void trataSIGINT(int sigNum) {
    nSIGINT = 1;/* set the flag as needed */
}
int main(void ){
        int pid;
        pid=fork();/* create child process */
        if(pid==0) {    
                //signal(SIGUSR1,trataSIGINT);/* instead of signal() use sigaction  */
                struct sigaction sa = {0}; /* initialize sa or fill all its members*/
                sa.sa_handler = trataSIGINT;/* set the handler to trataSIGINT*/
                sa.sa_flags = 0;
                sigemptyset(&sa.sa_mask);
                sigaction(SIGUSR1,&sa,NULL); /* when child received SIGUSR1, trataSIGINT gets called */
                pause(); /* wait until any signal received */
                /* do_something_child() code, this you want to run only after receiving signal */

        }
        else { 
                /* do_something_parent() */
                printf("parent about to send user signal to child\n");
                kill(pid,SIGUSR1); /*send SIGUSR1 to child */
                wait(0); /* wait till child completes  */
        }
        return 0;
}

旁注,用于在收到时设置标志,而不是将trataSIGINT()声明标志变量声明为类型类型。SIGUSR1int nSIGINT = 0;volatile sigatomic_t

来自 ISO/IEC 9899:2011 §7.14.1.1signal功能

¶5 如果信号不是作为调用abortor 函数的结果而出现的,则如果信号处理程序引用任何具有或线程存储持续时间的对象,而不是通过为声明为的对象分配一个值raise,则行为未定义,或者信号处理程序调用标准库中的任何函数,而不是 函数、函数、函数或信号函数,其第一个参数等于与导致调用处理程序的信号对应的信号编号。此外,如果对信号函数的这种调用导致 返回,则 的值是不确定的。252)staticlock-free atomic objectvolatile sig_atomic_tabort_Exitquick_exitSIG_ERRerrno

252) 如果任何信号由异步信号处理程序生成,则行为为undefined


推荐阅读