posix_spawn Linux:如何使子进程在终止时不进入僵尸状态

时间:2014-10-28 15:47:49

标签: c linux posix spawn zombie-process

我有一个进程使用posix_spawn()生成其他进程。当子进程自我终止时,它们进入僵尸状态,这是默认的预期行为。我希望它们完全终止,但是我无法使用posix_spawnattr_setflags()来实现它。也许我没有使用正确的旗帜。谁知道怎么做?

P.S。我希望子进程完全脱离并独立于父进程。

2 个答案:

答案 0 :(得分:3)

默认情况下,对exit()_exit()的调用会将调用进程的状态更改为Zombie,如果其父级仍处于活动状态。要更改此设置,您可以使用sigaction()

#include <signal.h>

struct sigaction arg = {
    .sa_handler=SIG_IGN,
    .sa_flags=SA_NOCLDWAIT // Never wait for termination of a child process.
};

sigaction(SIGCHLD, &arg, NULL);

在父进程中编写上述代码后,它将永远不会等待子进程,并且子进程将在完成后进入Terminated状态,而不是Zombie。

答案 1 :(得分:0)

父母必须等待其子女并阅读其退出状态。来自&#34; man wait&#34;:

A child that terminates, but has not been waited for becomes a "zombie".
The kernel maintains a minimal set of information about the zombie process (PID,
termination status, resource usage information) in order to allow  the parent to later
perform a wait to obtain information about the child.  As long as a zombie is not
removed from the system via a wait, it will consume a slot in the kernel process
table, and if this table fills, it will not be possible to create further
processes.
If a parent process terminates, then its "zombie" children (if any) are adopted by
init(8), which automatically performs a wait to remove the zombies.

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the
SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate 
do not become zombies and a call to wait() or  waitpid() will  block until all 
children have terminated, and then fail with errno set to ECHILD.  (The original POSIX 
standard left the behavior of setting SIGCHLD to SIG_IGN unspecified.  Note that even 
though the default disposition of SIGCHLD is "ignore", explicitly setting the 
disposition to SIG_IGN results in different treatment of zombie process children.)  
Linux 2.6 conforms to this specification.  However, Linux 2.4 (and earlier)  does  
not:  if  a wait()  or  waitpid()  call  is made while SIGCHLD is being ignored, the 
call behaves just as though SIGCHLD were not being ignored, that is, the call blocks 
until the next child terminates and then returns the process ID and status of that 
child.