note 36022 added to function.pcntl-fork
| From: | dfx at dfx dot at | Date: | Tue, 23 Sep 2003 11:09:42 +0000 |
| Subject: | note 36022 added to function.pcntl-fork | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-56959@lists.php.net to get a copy of this message | ||
small addition/clarification to joeldg at listbid.com 's note:
every unix process has a parent process. the parent process must be able to retrieve the exit status
of its child processes when a child terminates. the unique identifier of a process is its process id
(pid). when a child terminates, the parent process must use the child's pid to retrieve its
exit status. if a child process would simply disappear and vanish when it terminates, its pid may be
re-used by another process by the time the parent tries to retrieve the exit status. thus, a
terminated child process doesn't disappear, but becomes a zombie and keeps its place in the
process table, together with its pid. this avoids pid clashes in cases where the parent hasn't
retrieved the exit status of a terminated child.
it also means that a parent _must_ always retrieve the exit status of a terminated child, so that
the child is removed from the process table and the pid freed again for re-use. this is what the
wait*() family of function calls are for. wait()ing for already terminated processes is sometimes
called reaping: it gets rid of zombie processes.
for asynchronous operation, it makes sense not to wait() for the child until it terminates. unix
sends a signal to a parent process when a child terminates to notify it of this condition (SIGCHLD).
in a signal handler, it is possible to reap all terminated child processes. the parent can continue
to do work until the signal handler is called.
what happens when the parent terminates before the child terminates? this would mean that no parent
process is available to retrieve the child's exit status. when this happens, the child becomes
orphaned, and the "init" process automatically adopts it. "init" then takes care
of reaping any terminated processes.
this behavior, together with the double fork paradigm, can be used to achieve painless backgrounding
without having to deal with signal handlers and such: you fork once. the parent immediately wait()s
for the child's pid. the child immediately forks again and then immediately exits. this lets
the parent continue to do work. the child's child is then adopted by "init" and can
do the background work. when it terminates, "init" will reap it. the drawback is that the
parent has no way of getting the child's exit status.
code:
<?
$pid = pcntl_fork();
if (!$pid) {
$pid = pcntl_ffork();
if ($pid)
exit();
# the child can do its background work here
exit();
}
pcntl_waitpid($pid, &$status, 0);
?>
----
Manual Page -- http://www.php.net/manual/en/function.pcntl-fork.php
Edit Note -- http://master.php.net/manage/user-notes.php?action=edit+36022
Delete Note -- http://master.php.net/manage/user-notes.php?action=delete+36022&report=yes
Reject Note -- http://master.php.net/manage/user-notes.php?action=reject+36022&report=yes