diff options
author | Maik Hentsche <maik@mm-double.de> | 2010-06-15 17:19:41 +0200 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-06-15 17:19:41 +0200 |
commit | 0a18a49b281a5a76e75de77e45ee27ad1b807bb2 (patch) | |
tree | 2d8488cd6e8f77f1964d1a48fbe14065cfe8525b /pod/perlipc.pod | |
parent | ee84a7925f473937ece8b2db88bffc4400a8cabe (diff) | |
download | perl-0a18a49b281a5a76e75de77e45ee27ad1b807bb2.tar.gz |
Attempt at improving the perlipc docs
Diffstat (limited to 'pod/perlipc.pod')
-rw-r--r-- | pod/perlipc.pod | 38 |
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 |