我正在开发一个 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 );
}
非常感谢您!