通过以下代码示例,我希望我的子进程将正常退出:
int main(void)
{
for (int i = 0; i < 100; ++i)
{
int pid = fork();
printf("pid %d\n", pid);
sleep(1);
if (pid == 0)
exit(0);
}
}
但是当我运行ps
时,会得到以下输出:
5089 pts/0 00:00:00 test
5090 pts/0 00:00:00 test <defunct>
5091 pts/0 00:00:00 test <defunct>
5092 pts/0 00:00:00 test <defunct>
5094 pts/0 00:00:00 test <defunct>
如何使子进程正常退出?
答案 0 :(得分:4)
父进程必须调用wait
函数之一(wait,waitpid,waitid,wait4),以释放子进程资源。请参见waitpid的联机帮助页:
WAIT(2)
NAME
wait, waitpid, waitid - wait for process to change state
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
/* This is the glibc and POSIX interface; see
NOTES for information on the raw system call. */
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
waitid():
Since glibc 2.26: _XOPEN_SOURCE >= 500 ||
_POSIX_C_SOURCE >= 200809L
Glibc 2.25 and earlier:
_XOPEN_SOURCE
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE
DESCRIPTION
…
In the case of a terminated child, performing a wait
allows the system to release the resources associated with the child;
if a wait is not performed, then the terminated child remains in a
"zombie" state (see NOTES below).
答案 1 :(得分:1)
如果wait
未被父级调用,然后子级终止-那么它(子级)仍然是僵尸-无限期地等待其退出状态的获得。这就是您的情况。
如果您不想在父母中打电话给wait,那么您必须将孩子创建为独立的流程。 daemon()
可能 可以为您提供帮助。 http://man7.org/linux/man-pages/man3/daemon.3.html
答案 2 :(得分:1)
您的进程已正常退出。 <defunct>
表示该进程已死,唯一剩下的就是其PID和退出状态。
要清除进程表中的这些<defunct>
条目,父进程必须为其子进程使用wait()
或退出自身。在后一种情况下(父进程死亡),子进程变为孤立进程,并被init
(具有PID 1的进程)采用,然后对其进行清理。
在某些系统上, 1 您也可以忽略SIGCHLD
信号:
signal(SIGCHLD, SIG_IGN);
这意味着子进程将立即获得。
1 POSIX lists this feature作为XSI扩展。尽管不是POSIX一致性所必需的,但所有XSI conforming系统都将支持它。