diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2002-05-26 15:18:27 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2002-05-26 15:18:27 +0000 |
commit | 490f90af1ed9610036752df9ed6b23ca3afbb5e7 (patch) | |
tree | 23d7ad3e9f6a0e894ec177b8d0d4e0702a3f414c /pod/perlipc.pod | |
parent | 23525790a426250d01bfa89860d1f6b7435fbbe3 (diff) | |
download | perl-490f90af1ed9610036752df9ed6b23ca3afbb5e7.tar.gz |
Slight reformatting; tiny tweaks.
p4raw-id: //depot/perl@16796
Diffstat (limited to 'pod/perlipc.pod')
-rw-r--r-- | pod/perlipc.pod | 139 |
1 files changed, 77 insertions, 62 deletions
diff --git a/pod/perlipc.pod b/pod/perlipc.pod index 3535db49ce..58e063f4d0 100644 --- a/pod/perlipc.pod +++ b/pod/perlipc.pod @@ -10,14 +10,14 @@ IPC calls. Each is used in slightly different situations. =head1 Signals -Perl uses a simple signal handling model: the %SIG hash contains names or -references of user-installed signal handlers. These handlers will be called -with an argument which is the name of the signal that triggered it. A -signal may be generated intentionally from a particular keyboard sequence like -control-C or control-Z, sent to you from another process, or -triggered automatically by the kernel when special events transpire, like -a child process exiting, your process running out of stack space, or -hitting file size limit. +Perl uses a simple signal handling model: the %SIG hash contains names +or references of user-installed signal handlers. These handlers will +be called with an argument which is the name of the signal that +triggered it. A signal may be generated intentionally from a +particular keyboard sequence like control-C or control-Z, sent to you +from another process, or triggered automatically by the kernel when +special events transpire, like a child process exiting, your process +running out of stack space, or hitting file size limit. For example, to trap an interrupt signal, set up a handler like this: @@ -29,11 +29,13 @@ For example, to trap an interrupt signal, set up a handler like this: $SIG{INT} = 'catch_zap'; # could fail in modules $SIG{INT} = \&catch_zap; # best strategy -Prior to perl5.7.3 it was necessary to do as little as you possibly can in your handler; -notice how all we do is set a global variable and then raise an exception. That's because on -most systems, libraries are not re-entrant; particularly, memory allocation and I/O -routines are not. That meant that doing nearly I<anything> in your handler could in theory -trigger a memory fault and subsequent core dump - see L<Deferred Signals> below. +Prior to Perl 5.7.3 it was necessary to do as little as you possibly +could in your handler; notice how all we do is set a global variable +and then raise an exception. That's because on most systems, +libraries are not re-entrant; particularly, memory allocation and I/O +routines are not. That meant that doing nearly I<anything> in your +handler could in theory trigger a memory fault and subsequent core +dump - see L<Deferred Signals> below. The names of the signals are the ones listed out by C<kill -l> on your system, or you can retrieve them from the Config module. Set up an @@ -217,14 +219,15 @@ to find out whether anyone (or anything) has accidentally removed our fifo. =head2 Deferred Signals -In perls before perl5.7.3 by installing Perl code to deal with signals, you were exposing -yourself to danger from two things. First, few system library functions are -re-entrant. If the signal interrupts while Perl is executing one function -(like malloc(3) or printf(3)), and your signal handler then calls the -same function again, you could get unpredictable behavior--often, a -core dump. Second, Perl isn't itself re-entrant at the lowest levels. -If the signal interrupts Perl while Perl is changing its own internal -data structures, similarly unpredictable behaviour may result. +In Perls before Perl 5.7.3 by installing Perl code to deal with +signals, you were exposing yourself to danger from two things. First, +few system library functions are re-entrant. If the signal interrupts +while Perl is executing one function (like malloc(3) or printf(3)), +and your signal handler then calls the same function again, you could +get unpredictable behavior--often, a core dump. Second, Perl isn't +itself re-entrant at the lowest levels. If the signal interrupts Perl +while Perl is changing its own internal data structures, similarly +unpredictable behaviour may result. There were two things you could do, knowing this: be paranoid or be pragmatic. The paranoid approach was to do as little as possible in your @@ -237,66 +240,78 @@ The pragmatic approach was to say ``I know the risks, but prefer the convenience'', and to do anything you wanted in your signal handler, and be prepared to clean up core dumps now and again. -In perl5.7.3 and later to avoid these problems signals are "deferred" - that is when the -signal is delivered to the process by the system (to the C code that implements perl) a flag -is set, and the handler returns immediately. Then at strategic "safe" points in the perl -interpreter (e.g. when it is about to execute a new opcode) the flags are checked -and the perl level handler from %SIG is executed. The "deferred" scheme allows much more -flexibility in the coding of signal handler as we know perl interpreter is in a -safe state, and that we are not in a system library function when the handler is called. -However the implementation does differ from previous perls in the following ways: +In Perl 5.7.3 and later to avoid these problems signals are +"deferred"-- that is when the signal is delivered to the process by +the system (to the C code that implements Perl) a flag is set, and the +handler returns immediately. Then at strategic "safe" points in the +Perl interpreter (e.g. when it is about to execute a new opcode) the +flags are checked and the Perl level handler from %SIG is +executed. The "deferred" scheme allows much more flexibility in the +coding of signal handler as we know Perl interpreter is in a safe +state, and that we are not in a system library function when the +handler is called. However the implementation does differ from +previous Perls in the following ways: =over 4 =item Long running opcodes -As perl interpreter only looks at the signal flags when it about to execute a new -opcode if a signal arrives during a long running opcode (e.g. a regular expression -operation on a very large string) then signal will not be seen until operation completes. +As Perl interpreter only looks at the signal flags when it about to +execute a new opcode if a signal arrives during a long running opcode +(e.g. a regular expression operation on a very large string) then +signal will not be seen until operation completes. =item Interrupting IO -When a signal is delivered (e.g. INT control-C) the operating system breaks into -IO operations like C<read> (used to implement perls E<lt>E<gt> operator). On -older perls the handler was called immediately (and as C<read> is not "unsafe" this -worked well). With the "deferred" scheme the handler is not called immediately, -and if perl is using system's C<stdio> library that library may re-start the C<read> -without returning to perl and giving it a chance to call the %SIG handler. If this -happens on your system the solution is to use C<:perlio> layer to do IO - at least -on those handles which you want to be able to break into with signals. (The C<:perlio> -layer checks the signal flags and calls %SIG handlers before resuming IO operation.) +When a signal is delivered (e.g. INT control-C) the operating system +breaks into IO operations like C<read> (used to implement Perls +E<lt>E<gt> operator). On older Perls the handler was called +immediately (and as C<read> is not "unsafe" this worked well). With +the "deferred" scheme the handler is not called immediately, and if +Perl is using system's C<stdio> library that library may re-start the +C<read> without returning to Perl and giving it a chance to call the +%SIG handler. If this happens on your system the solution is to use +C<:perlio> layer to do IO - at least on those handles which you want +to be able to break into with signals. (The C<:perlio> layer checks +the signal flags and calls %SIG handlers before resuming IO operation.) + +Note that the default in Perl 5.7.3 and later is to automatically use +the C<:perlio> layer. =item Signals as "faults" -Certain signals e.g. SEGV, ILL, BUS are generated as a result of virtual memory or -other "faults". These are normally fatal and there is little a perl-level handler -can do with them. (In particular the old signal scheme was particularly unsafe -in such cases.) However if a %SIG handler is set the new scheme simply sets a flag -and returns as described above. This may cause the operating system to try the -offending machine instruction again and - as nothing has changed - it will generate -the signal again. The result of this is a rather odd "loop". In future perl's signal -mechanism may be changed to avoid this - perhaps by simply disallowing %SIG handlers -on signals of that type. Until then the work-round is not to set a %SIG handler on -those signals. (Which signals they are is operating system dependant.) +Certain signals e.g. SEGV, ILL, BUS are generated as a result of +virtual memory or other "faults". These are normally fatal and there +is little a Perl-level handler can do with them. (In particular the +old signal scheme was particularly unsafe in such cases.) However if +a %SIG handler is set the new scheme simply sets a flag and returns as +described above. This may cause the operating system to try the +offending machine instruction again and - as nothing has changed - it +will generate the signal again. The result of this is a rather odd +"loop". In future Perl's signal mechanism may be changed to avoid this +- perhaps by simply disallowing %SIG handlers on signals of that +type. Until then the work-round is not to set a %SIG handler on those +signals. (Which signals they are is operating system dependant.) =item Signals triggered by operating system state -On some operating systems certain signal handlers are supposed to "do something" -before returning. One example can be CHLD or CLD which indicates a child process -has completed. On some operating systems the signal handler is expected to C<wait> -for the completed child process. On such systems the deferred signal scheme will -not work for those signals (it does not do the C<wait>). Again the failure will -look like a loop as the operating system will re-issue the signal as there are -un-waited-for completed child processes. +On some operating systems certain signal handlers are supposed to "do +something" before returning. One example can be CHLD or CLD which +indicates a child process has completed. On some operating systems the +signal handler is expected to C<wait> for the completed child +process. On such systems the deferred signal scheme will not work for +those signals (it does not do the C<wait>). Again the failure will +look like a loop as the operating system will re-issue the signal as +there are un-waited-for completed child processes. =back 4 =head1 Using open() for IPC -Perl's basic open() statement can also be used for unidirectional interprocess -communication by either appending or prepending a pipe symbol to the second -argument to open(). Here's how to start something up in a child process you -intend to write to: +Perl's basic open() statement can also be used for unidirectional +interprocess communication by either appending or prepending a pipe +symbol to the second argument to open(). Here's how to start +something up in a child process you intend to write to: open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") || die "can't fork: $!"; |