【发布时间】:2013-04-18 07:08:47
【问题描述】:
所以,我的任务是以这种方式同步父母和他的 2 个孩子: 一个孩子向父母发送 SIGUSR2 信号,然后阻止等待父母的消息。 同步是由全局标志实现的,所以父等待任何一个 flag_ch 变为 1(当子发送 SIGUSR2 时发生),然后向该子发送信号 SIGUSR1,子恢复(导致全局 flag_p 变为 1)
问题是父母只收到一个孩子的信号,然后阻塞等待第二个孩子的信号,但他们没有出现 . 有什么想法吗?..
#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;
}
【问题讨论】:
-
你是不是故意写的 while (0 == flag_p) { }; ?
-
@AnishRam 不,孩子在父亲中获得的价值是孩子的 pid。
-
'while (0 == flag_p) { };'阻止孩子,直到父母的信号被释放
-
但是 flag_p 没有相互连接。每个进程都有自己的 flag_p
-
这就是为什么我使用父母发送给孩子的信号 SIGUSR1 来更改 flag_p 值
标签: c linux synchronization signals