如何用C中的信号同步两个进程(子进程和父进程)?

时间:2018-06-28 03:53:49

标签: c process signals

我想使用信号(SIGUSR1)来同步C中的进程。我希望父进程等待一个信号,当接收到该信号时,将相同的信号发送给子进程。我写了一段简短的文字来刺激推理,但是并没有消失。

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

输出

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

1 个答案:

答案 0 :(得分:1)

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

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

  

返回值          pause()仅在返回signal was caughtsignal-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()时在SIGUSR1中设置标志,而不是声明int nSIGINT = 0;声明标志变量为volatile sigatomic_t类型。

  

根据ISO / IEC 9899:2011§7.14.1.1signal函数

     

¶5如果信号不是由于调用abort或   raise函数,如果信号处理程序的行为未定义   引用具有static或线程存储持续时间为   除了为lock-free atomic object分配一个值   声明为volatile sig_atomic_t的对象或信号处理程序   调用标准库中除abort之外的任何函数   函数,_Exit函数,quick_exit函数或   第一个参数等于信号编号的信号函数   对应于引起处理程序调用的信号。   此外,如果对信号函数的这种调用导致   SIG_ERR返回,errno的值不确定。252)

     

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