summaryrefslogtreecommitdiff
path: root/pod/perlipc.pod
diff options
context:
space:
mode:
authorMaik Hentsche <maik@mm-double.de>2010-06-15 17:19:41 +0200
committerRafael Garcia-Suarez <rgs@consttype.org>2010-06-15 17:19:41 +0200
commit0a18a49b281a5a76e75de77e45ee27ad1b807bb2 (patch)
tree2d8488cd6e8f77f1964d1a48fbe14065cfe8525b /pod/perlipc.pod
parentee84a7925f473937ece8b2db88bffc4400a8cabe (diff)
downloadperl-0a18a49b281a5a76e75de77e45ee27ad1b807bb2.tar.gz
Attempt at improving the perlipc docs
Diffstat (limited to 'pod/perlipc.pod')
-rw-r--r--pod/perlipc.pod38
1 files changed, 37 insertions, 1 deletions
diff --git a/pod/perlipc.pod b/pod/perlipc.pod
index 4f6c0f0484..8d9ea9757d 100644
--- a/pod/perlipc.pod
+++ b/pod/perlipc.pod
@@ -150,7 +150,43 @@ or better still:
$SIG{CHLD} = \&REAPER;
# do something that forks...
-Signal handling is also used for timeouts in Unix, While safely
+Note: qx(), system() and some modules for calling external commands do a
+fork() and wait() for the result. Thus, your signal handler (REAPER in the
+example) will be called. Since wait() was already called by system() or qx()
+the wait() in the signal handler will not see any more zombies and therefore
+block.
+
+The best way to prevent this issue is to use waitpid, as in the following
+example:
+
+ use POSIX ":sys_wait_h"; # for nonblocking read
+
+ my %children;
+
+ $SIG{CHLD} = sub {
+ # don't change $! and $? outside handler
+ local ($!,$?);
+ my $pid = waitpid(-1, WNOHANG);
+ return if $pid == -1;
+ return unless defined $children{$pid};
+ delete $children{$pid};
+ cleanup_child($pid, $?);
+ };
+
+ while (1) {
+ my $pid = fork();
+ if ($pid == 0) {
+ # ...
+ exit 0;
+ } else {
+ $children{$pid}=1;
+ # ...
+ system($command);
+ # ...
+ }
+ }
+
+Signal handling is also used for timeouts in Unix. While safely
protected within an C<eval{}> block, you set a signal handler to trap
alarm signals and then schedule to have one delivered to you in some
number of seconds. Then try your blocking operation, clearing the alarm