我有一个父进程,它根据传递给程序的第一个参数产生X个子进程(播放器)。产生每个孩子后,它会向他们发送信号。现在我想让孩子们一直打印他们收到信号并退出,但他们似乎没有得到父母的信号。孩子们没有得到信号,还是我处理不对?
父:
#define _POSIX_SOURCE
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void reciveCard() {
write(1, "signal recived\n", 15);
exit(0);
}
int main(int argc, char **argv) {
int numPlayers, i;
int *kpids;
numPlayers = atoi(argv[1]);
kpids = malloc(numPlayers * sizeof(int));
signal(SIGUSR1, SIG_IGN);
for(i = 0; i < numPlayers; i++) {
if((kpids[i] = fork()) == 0) {
if(execlp("./player\0", "./player\0", (char *) NULL) == -1) {
printf("error\n");
exit(1);
}
}
}
for(i = 0; i < numPlayers; i++) {
printf("%d\n", kpids[i]);
kill(kpids[i], SIGUSR1);
}
wait(NULL);
return 0;
}
子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void reciveCard() {
write(1, "signal recived\n", 15);
exit(0);
}
int main() {
signal(SIGUSR1, reciveCard);
while(1) {
sleep(1);
}
return 0;
}
答案 0 :(得分:2)
你有竞争条件。
父程序执行fork
调用,因此快速它会落入kill
循环,之后任何孩子都有机会这样做execlp
。
因此,孩子不能足够快地设置处理程序。也就是说,当信号进入时,孩子仍然会忽略它,因为它已经继承了父母的SIG_IGN
电话。
现在,在execlp
之后,孩子将设置处理程序,但信号已经已经,因此处理程序永远不会被调用
要看到这一点,请在两个父循环之间添加sleep(1)
,它应该可以正常工作。