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

如何用C语言同步两个进程(子进程和父进程)的信号?,c,process,signals,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 ma

我想用信号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();
    }
}
简单提示是使用pause和kill,即pause用于阻止进程执行,直到接收到任何信号,一旦接收到信号,则执行某些操作,kill用于发送SIGUSR1信号

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

返回值 仅当捕捉到信号并返回信号捕捉功能时,暂停才会返回。 在这种情况下,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;
}
旁注,用于在收到SIGUSR1时在trataSIGINT中设置标志,而不是声明int nSIGINT=0;将标志变量声明为volatile sigu原子类型的类型

根据ISO/IEC 9899:2011§7.14.1.1,信号功能

如果信号不是由于调用中止或 raise函数,如果信号处理程序 指具有静态或线程存储持续时间的任何对象 不是无锁原子对象,除非通过将值指定给 对象声明为volatile sig_atomic_t或信号处理程序 调用标准库中除中止以外的任何函数 函数、退出函数、快速退出函数或 第一个参数等于信号编号的信号函数 对应于导致调用处理程序的信号。 此外,如果对信号函数的这种调用导致 SIG_ERR return,errno的值不确定。252

252如果异步信号处理程序生成任何信号,则 行为是未定义的


也许试着在家长中等待信号,然后试着向家长发送信号。我怎么做?我不知道如何等待信号,我不想用忙碌的等待。你能告诉我怎么用这个吗?我可以设置一个特殊的信号,以便在暂停后继续代码?尝试sigaction-检查并更改信号操作。要了解更多详细信息,只需键入man sigaction。请注意,如果收到任何信号,pause都会返回i。您可能希望将其放入一个循环中,以检查接收到的volatile int usr1_;并在SIGUSR1的信号处理程序中将其设置为true。并避免任何已经使用SIGUSR1本身的库。最好使用posix互斥量和条件。是true@GoswinvonBrederlow或volatile-sigatomic_t usr1_-received;最好是始终以原子方式访问sigatomic_t类型,并避免中断变量访问的不确定性。什么是kill0,SIGUSR1?它应该是killpid,SIGUSR1;为什么要在父进程中暂停?删除它,一个接一个。请说明否决投票的原因。
//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;
}