Sigsuspend 导致第二个孩子无法在 C 中接收管道消息

问题描述 投票:0回答:0

我正在开发一个 C 程序,我想用它来实现一个场景,当父进程和两个子进程通过为每个子进程保留的两个单独的 FIFO 相互通信时。在此之前,两个孩子都应该向父母发送信号。那不是问题。但是,如果父母想要写入 FIFO 以便第二个孩子访问其消息,那么我将无法实现预期的目标。

我试图在

SIGUSR1
SIGUSR2
常量的帮助下完成预期的结果。分别为第一个和第二个孩子保留。首先,父母必须接收所有信号。只有这样,它才会通过 FIFO 将消息发送给两个孩子。在父级中,我尝试打开 FIFO 仅用于写入。在 sigqueue 调用之后的孩子中,我尝试打开 FIFO 以供只读。

我体验到只有第一个孩子收到短信然后执行就挂了

我知道

printf()
在处理程序函数体内是不需要的,但我只是为了实验目的而包括它。

#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

#define CHLD_1_NOTIFY_PARENT SIGUSR1
#define CHLD_2_NOTIFY_PARENT SIGUSR2
#define PARENT_NOTIFY_CHLD_1 SIGUSR1
#define PARENT_NOTIFY_CHLD_2 SIGUSR2

int main()
{
    pid_t parent_pid, pid, pid_2;
    sigset_t newmask, oldmask;
    union sigval value;
    struct sigaction action;
    int fds[2];
    pipe(fds);

    int fds_2[2];
    pipe(fds_2);

    parent_pid = getpid();

    if ( (pid = fork() ) ) 
    {    /*parent*/

        void parent_handler( int signo, siginfo_t* info, void* context );

        sigemptyset(&newmask); 
        sigaddset(&newmask, CHLD_1_NOTIFY_PARENT); 
        sigaddset(&newmask, CHLD_2_NOTIFY_PARENT); 
        sigprocmask(SIG_BLOCK, &newmask, &oldmask); 

        action.sa_flags = SA_SIGINFO; 
        action.sa_sigaction = parent_handler;

        if (sigaction(CHLD_1_NOTIFY_PARENT, &action, NULL) == -1) { 
            perror("sigusr: sigaction");
            
        }

        if (sigaction(CHLD_2_NOTIFY_PARENT, &action, NULL) == -1) { 
            perror("sigusr: sigaction");
            
        }

        if( ( pid_2 = fork() )== 0 ) //2. child
        {   
            printf("2. child started\n");
            
            value.sival_int = 43;

            sigqueue( parent_pid, CHLD_2_NOTIFY_PARENT, value );

            printf("2. child sends CHLD_2_NOTIFY_PARENT\n");
            
            close(fds[0]);
            close(fds[1]);
            close(fds_2[1]);
            char buffer[6];
            read(fds_2[0], buffer, sizeof(buffer));
            printf("2. child receives through pipe: %s.\n", buffer);
            close(fds_2[0]);
            
            printf("2. child terminates\n");

        }
        else
        {
            //value.sival_int = 44;

            //sigqueue( pid, PARENT_NOTIFY_CHLD_1, value );

            sleep(1); 

            sigsuspend(&oldmask);
            
            close(fds[0]);
            write(fds[1], "hello", 6);
            wait(NULL);
            

            sigsuspend(&oldmask);
            close(fds[1]);
            close(fds_2[0]);
            write(fds_2[1], "hello", 6);
            wait(NULL);
            close(fds_2[1]);

            waitpid(pid,  NULL, 0 );
            waitpid( pid_2, NULL, 0 );
            printf("Parent terminates\n");
        }
        
    }
    else /* 1. child */
    {                 
        printf("1. child starts\n");

        //void chld_handler( int signo, siginfo_t* info, void* context );

        sigemptyset(&newmask); 
        sigaddset(&newmask, PARENT_NOTIFY_CHLD_1); 
        
        sigprocmask(SIG_BLOCK, &newmask, &oldmask);

        action.sa_flags = SA_SIGINFO; 
        //action.sa_sigaction = chld_handler;

        if (sigaction( PARENT_NOTIFY_CHLD_1, &action, NULL) == -1) { 
            perror("sigusr: sigaction");
            
        }

        value.sival_int = 42;
        
        sigqueue( parent_pid, CHLD_1_NOTIFY_PARENT, value );

        printf("1. child sends CHLD_1_NOTIFY_PARENT signal to parent\n");

        close(fds[1]);
        char buffer[6];
        read(fds[0], buffer, sizeof(buffer));
        printf("1. child receives through pipe: %s.\n", buffer);
        close(fds[0]);
        
        printf("1. child terminates\n");
     
     }
}
void parent_handler(int signo, siginfo_t* info, void* context) 
{
    int int_msg = info->si_value.sival_int;
    int chld = 2;
    if( int_msg % 2 == 0 )
    {   
        chld = 1;

    }
    
    printf("parent receives %i from child %i. with data %i\n", signo, chld, int_msg );
       
}

非常感谢您!

c pipe signals ipc
© www.soinside.com 2019 - 2024. All rights reserved.