gpt4 book ai didi

c - 为什么这个程序会创建一个僵尸进程,我该如何修复它?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:38 27 4
gpt4 key购买 nike

我的问题是我无法理解为什么代码仍然会生成僵尸进程。我该如何解决?谢谢。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>


int count = 0;

/**
* signal callback
* @param signo
*/
void sigcallback(int signo) {
short stime = 5;
int status;
wait(&status);
while (1) {

printf("wake up,%d\n", getpid());
sleep((stime + 1) - (short) (time(NULL) % stime));

}
}

int call_cmd(void) {
count++;

int i;
pid_t pid;
signal(SIGCHLD, sigcallback);
for (i = 0; i < 3; i++) {
if ((pid = fork()) < 0) {
printf("error with fork\n");
exit(1);
} else if (pid > 0) {
waitpid(pid, NULL, WNOHANG);
} else {
printf("\t\t\tsid is %d,count is %d,pid is %d\n", getsid(getpid()), count, getpid());
}
}
return 1;
}

void notice_root(int signo) {
printf("execut root signal\n");
waitpid(0, NULL, 0);
}

int main(void) {
pid_t pid;

int i;
signal(SIGCHLD, notice_root);
for (i = 0; i < 2; i++) {
if ((pid = fork()) < 0) {
printf("error with fork\n");
exit(1);
} else if (pid > 0) {
exit(0);
} else {
setsid();
call_cmd();
}
}
return 0;
}

最佳答案

您的信号处理程序 sigcallback 中有一个无限 sleep 循环。一旦该函数处理了一个信号,该进程将永远不会再处理另一个 SIGCHLD 信号,因为信号处理程序永远不会返回。这可能是您的僵尸的原因。

您不会为每个退出的 child 都收到一个信号。如果两个 child “同时”退出,您只会收到一个 SIGCHLD 传递。因此,当您在信号处理程序(其中任何一个)中等待时,您应该循环等待以获取所有已退出的子级。类似的东西:

for (;;) {
pid_t p = waitpid(-1, 0, WNOHANG);
if (p <= 0) break;
/* ... */
}

当您的进程退出时,该进程的子进程将由 init 进程继承,因此它们将被正确回收。但是,您的无限循环阻止了 3 件事:

  • 它不会收获同时退出的 child 。
  • 在收获第一个后,它不会再收获更多的 child 。
  • 它不会允许进程退出,因此 init 进程无法收割子进程。

关于c - 为什么这个程序会创建一个僵尸进程,我该如何修复它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16967694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com