したがって、私のタスクは、親とその 2 人の子供をこの方法で同期させることです。1 つの子供が SIGUSR2 シグナルを親に送信し、待機中の親メッセージをブロックします。同期はグローバル フラグによって実装されるため、親は flag_ch のいずれかが 1 になるのを待機し (子が SIGUSR2 を送信したときに発生します)、シグナル SIGUSR1 をこの子に送信し、子は再開します (グローバル flag_p が 1 になるため)。
問題は、親が 1 つの子からのみシグナルを受信し、次に 2 番目の子シグナルを待機するのをブロックすることですが、それらは表示されません。何か案が?..
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/signalfd.h>
#define LPC 10
pid_t ch[2];
sig_atomic_t flag_ch[2] = {0, 0};
sig_atomic_t flag_p = 0;
int get_ind(pid_t ch_pid) {
int i;
for (i = 0; i < 2; ++i) {
if (ch_pid == ch[i])
return i;
}
return -1;
}
void usr_handler(int signo, siginfo_t* si, void* unused) {
int ch_index;
switch(signo) {
case SIGUSR2:
ch_index = get_ind(si->si_pid);
if (ch_index >= 0)
flag_ch[ch_index] = 1;
else
fprintf(stderr, "signal handled not from child pid %d\n", si->si_pid);
break;
case SIGUSR1:
flag_p = 1;
break;
}
}
void set_usr_handler(void) {
struct sigaction sa;
sa.sa_sigaction = usr_handler;
sa.sa_flags = SA_SIGINFO;
sa.sa_restorer = NULL;
sigemptyset(&sa.sa_mask);
if (0 != sigaction(SIGUSR1, &sa, NULL))
abort_prg("signal [SIGUSR1] error");
if (0 != sigaction(SIGUSR2, &sa, NULL))
abort_prg("signal [SIGUSR2] error");
}
void child_proc(void) {
int i;
for (i = 0; i < LPC; ++i) {
if (0 != kill(getppid(), SIGUSR2))
exit(1);
while (0 == flag_p) { };
flag_p = 0;
}
}
int wait_child(void) {
while (0 == flag_ch[0] && 0 == flag_ch[1]) { };
if (1 == flag_ch[0]) {
flag_ch[0] = 0;
return ch[0];
}
flag_ch[1] = 0;
return ch[1];
}
void parent_proc(void) {
int i;
pid_t ch_pid;
for (i = 0; i < LPC * 2; ++i) {
ch_pid = wait_child();
printf("Parent: Received from pid [%d]\n", ch_pid);
if (0 != kill(ch_pid, SIGUSR1))
exit(1);
}
}
int main(int argc, char* argv[]) {
set_usr_handler();
int i;
for (i = 0; i < 2; ++i) {
pid_t child = fork();
if (0 > child)
exit(1);
if (0 == child) {
child_proc();
return 0;
}
ch[i] = child;
}
parent_proc();
return 0;
}