为什么孩子们不能重现信号

时间:2017-07-20 19:07:20

标签: c signals system-calls

我有一个父进程,它根据传递给程序的第一个参数产生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;
}

1 个答案:

答案 0 :(得分:2)

你有竞争条件。

父程序执行fork调用,因此快速它会落入kill循环,之后任何孩子都有机会这样做execlp

因此,孩子不能足够快地设置处理程序。也就是说,当信号进入时,孩子仍然会忽略它,因为它已经继承了父母的SIG_IGN电话。

现在,在execlp之后,孩子将设置处理程序,但信号已经已经,因此处理程序永远不会被调用

要看到这一点,请在两个父循环之间添加sleep(1),它应该可以正常工作。