如何使用信号在进程之间进行同步?

How to make synchronization between processes using signals?

objective 是 parent 进程应该生成一个 child,parent 打印 1 到 100 之间的偶数,child打印奇数。这种机制应该使用信号来实现(显然数字应该按顺序排列,例如 parent:0、child:1、parent:2...)我编写了以下代码:

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>

int main(){
    pid_t pid;

    pid = fork();

    if (pid == -1){
        return 1;
    }
    
    if (pid == 0){
            
        for(int i=0; i<=100; i++){
            if (i % 2 != 0){
                printf("I am the child: %d\n", i);
            }
        }

    } else {
        kill(pid, SIGSTOP);
        for(int i=0; i<=100; i++){
            if(i % 2 == 0){
                printf("I am the parent: %d\n", i);
                kill(pid, SIGCONT);
            }
        }
        wait(NULL);
    }

    return 0;
}

但是输出不是按照应有的顺序,parent 首先打印他的所有数字,child 紧随其后。我想知道 SIGSTOP 和 SIGCONT 是不是适合使用的信号,但没有其他合理的解决方案。

任何建议都会有所帮助。谢谢。

阻止信号并仅在收到该信号时恢复。关于使用哪个信号,您可以使用任何可以被阻止的信号(除 SIGKILLSIGSTOP 之外的任何信号)。我使用 SIGRTMIN 因为它是用于应用程序定义的目的。

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>

int main(){
    /* Block SIGRTMIN */

    sigset_t sigmask;

    sigemptyset(&sigmask);
    sigaddset(&sigmask, SIGRTMIN);

    if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0)
        exit(1);
    
    int signo;

    /* Spawn a new child */

    pid_t pid;

    pid = fork();

    if (pid == -1){
        return 1;
    }
    
    if (pid == 0){
        sigwait(&sigmask, &signo);  // This is to make parent start first.
        for(int i=1; i<=100; i=i+2){
            printf("I am the child: %d\n", i);

            kill(getppid(), SIGRTMIN);  // Resume parent
            sigwait(&sigmask, &signo);  // Wait for parent
        }

    } else {
        for(int i=0; i<=100; i=i+2){
            printf("I am the parent: %d\n", i);

            kill(pid, SIGRTMIN);    // Resume child
            if (i == 100)   // Parent stucks at sigwait after printing 100.
                break;
            sigwait(&sigmask, &signo);  // Wait for child
        }
        wait(NULL);
    }

    return 0;
}

我们在父级中阻止了 SIGRTMIN 但它如何在子级中被阻止?

根据 signal(7) 手册页。

A child created via fork(2) inherits a copy of its parent's signal mask; the signal mask is preserved across execve(2).