使用 fork() 创建 "background running" children 并用信号杀死它们中的每一个

Creating "background running" children with fork() and kill each of them with signals

我需要从同一个 parent 创建 n children,并让它们 运行 而 parent无限请求信号发送给某些 child。我让 parent 创建了那些 n children,但是它们执行完了,所以我让它们进入 while(1) 循环。问题是,当我试图杀死任何 child 时,它变成了一个僵尸进程,而不是真正终止它的执行。我猜那是因为 parent 仍在等待 children 终止执行并且他们不发送退出状态。所以...首先,我真的需要让 children 进入一个无限的 while 循环,使它们成为 运行 而 parent 正在请求信号吗?如果我这样做,我该如何避免这个 "never terminating execution" 问题?我需要找到一种方法让 children 退出 while 循环并发送实际的 "finished execution" 信号,因为我认为我不能使用 wait() 因为 children从未真正完成 运行,它们只是被 parent.

终止

谢谢。 PS:运行 在 Linux。这是我的代码

int main(){
    int i;
    pid_t parent = getpid();
    pid_t pid[4];
    printf("parent with pid %d\n", parent);

    for(i = 0; i < 5; i++){
        pid[i] = fork();
        if(pid[i] < 0){
            perror("Error in fork.");
            exit(1);
        } else if(pid[i] == 0 && getppid() == padre) {
            printf("Number: %d   pid %d, parent: %d\n", i, getpid(), getppid());
            while(1);
        }
    }

    if(getpid() == padre){
        while(1){
            printf("Enter pid and signal:\n");
            int x, y;
            scanf("%d", &x); // pid
            scanf("%d", &y); // signal
            printf("you did: kill(%d, %d)\n", x, y);
            kill(x, y);
        }
    }
    return 0;
}

编辑: 实施答案的最终代码:https://github.com/sebasura/sistope

The problem is, when I try to kill any child, it becomes a zombie process instead of actually terminating its execution.

好吧,是也不是。成为僵尸通常是在进程终止时发生的,直到该进程被其 parent 收集。僵尸在table的过程中占用了一点space,但不是运行,因此不消耗CPU .

I'm guessing that's because the parent is still waiting for the children to terminate execution and they don't send the exit status.

不是,因为kill()只是发出信号。您需要使用 wait() 函数之一——也许是 waitpid()——来实际收集终止的 child.

So... First of all, do I really need to make the children enter an infinite while loop to make them be running while the parent is asking for the signals?

没有。 child 可以使用 sigwait() 或其变体之一来等待来自指定集合的​​信号,或者 pause() 暂停执行等待接收到终止进程或触发信号的任何信号处理函数。但是请注意,有些信号在默认情况下不执行这两种操作,因此 sigwait() 可能是更好的选择。

If I do, how do I avoid this "never terminating execution" problem?

child 必须因收到信号而终止。这已经发生在你身上,因为 children 正在变成僵尸。对于您当前的代码,它可能取决于您发送的信号,但是,因为有些代码的默认处理不会终止进程。

谢谢大家,我做到了。 我用 pause() 而不是 while(1).

杀完之后,我用了这个:

int state;
waitpid(pid, &state, 0);

这是作业的一部分,所以我会在截止日期后上传代码,这样他们就不会因为分享代码或其他事情而惩罚我。

再次感谢。 编辑: 这是最终代码 https://github.com/sebasura/sistope