从父母向孩子发送信号,反之亦然

Posted

技术标签:

【中文标题】从父母向孩子发送信号,反之亦然【英文标题】:Sending signal from parent to child and vice-versa 【发布时间】:2016-01-23 22:42:57 【问题描述】:

我正在尝试练习信号并试图实现以下目标

1) 孩子和父母打印10个数字并将接力棒传给其他人

2) Parent/Child 通过 sigsuspend 等待那里转

3) sigaction 只是为了捕捉信号

4) 使用 kill 发送带有相应进程 ID 的信号

但是输出被竞争条件破坏了,我看到一旦父母从孩子控制中获得信号就永远不会交还给孩子

我还希望 sigaction 也能捕捉到似乎没有发生的信号。

你能指出我做错了什么吗?

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

static volatile int count = 0;

void sighandler(int sig)

    if (sig == SIGUSR1)
    
        printf(" \n child sends parent signal - \n ");
    

    if (sig == SIGUSR2)
    
        printf("\n parent sends child signal - \n ");
    


int main(void)

    //pid_t pid, cid;
    sigset_t block_csignal, block_psignal, empty_signal;
    struct sigaction ccatch, pcatch;

    setbuf(stdout, NULL);

    /* Creating signal set for suspending process till
       it receives below signal */
    sigfillset(&block_csignal);
    sigdelset(&block_csignal, SIGUSR2);

    sigfillset(&block_psignal);
    sigdelset(&block_psignal, SIGUSR1);

    /* Creating signal set for catching the signal
       and changing signal disposition */
    sigemptyset(&ccatch.sa_mask);   /* ccatch for catching signal from parent */
    ccatch.sa_flags = 0;
    ccatch.sa_handler = sighandler;

    sigemptyset(&pcatch.sa_mask);  /*  pcatch for catching signal from child */
    pcatch.sa_flags = 0;
    pcatch.sa_handler = sighandler;

    sigaction(SIGUSR2, &ccatch, NULL); /* catch signal from parent for child */
    sigaction(SIGUSR1, &pcatch, NULL); /* catch signal from child for parent */

    switch(fork())
    
        case -1:
            printf("error in child creation \n ");
            exit(-1);
        case 0:
            printf(" \n Control in hand of child \n ");

            while(count < 50)
            
                int temp = 0;
                printf(" \n c count ---  \n ");
                while (temp < 10)
                
                    printf(" %d ", count);
                    temp++;
                    count++;
                
                printf(" \n parent id in child process --- %d \n ", getppid());
                kill(getppid(), SIGUSR1);  /* send signal to parent */
                sigsuspend(&block_csignal); /* wait till you get signal from parent */

            
            exit(1);
        default:
            printf("\n Control in hand of parent \n ");
            sigsuspend(&block_psignal); /*wait till you get signal from child*/
            printf("\n Control back in hand of parent \n ");
            while (count < 50)
            
                int temp = 0;
                printf(" \n p count ---  \n ");
                while (temp < 10)
                
                    printf(" %d ", count);
                    temp++;
                    count++;
                
                kill(getpid(), SIGUSR2); /* send signal to child */
            
            break;
    

    printf("\n ");
    return EXIT_SUCCESS;

【问题讨论】:

你考虑过用message queues代替信号吗? 为什么是第一个分叉,I.E.cid = fork() ?不确定得到它...在这里,您将有一位父母和 3 个孩子。是自愿的吗? @e0k - 是的,我知道使用 PIPE/FIFO/MessageQ 可能是完成我想要完成的任务的更好方法,但我正在练习 Signals,并且相信这样的例子虽然效率不高,但会帮助我了解我是否正确理解信号:) 是的,你有两个fork()s,你的意思可能是你的switch语句是switch (cid) @Shitsu - 抱歉,在发帖之前忘记删除错字了。我已经编辑了代码,我仍然看到同样的问题 【参考方案1】:

为了从父级向子级发送信号,您首先需要存储子级的 pid(它是成功分叉的返回值)。在父代码中,您使用 getpid() 返回当前正在运行的进程的 id,因此是父进程。

尝试类似:

  int cid = fork();
  if(cid == 0) //child
  if(cid > 0) // parent
    //... 
    kill(cid,... 
 

【讨论】:

以上是关于从父母向孩子发送信号,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

从父母发送消息给孩子

向父母发送信号不起作用

带子进程的双向管道

Linux信号:孩子没有收到

如何让子进程等待信号?

如何让“Pointermove”委托在父母/孩子的Safari iOS中工作?