X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2Fthreads%2Fthreads.pm;h=2970321f7b40254c2e3bba660924794bf5567c6e;hb=de1254415ffeb03ba71a0802be6f212b10153304;hp=6fcd431ded82f7a17f6a6204b540ba044a87fea8;hpb=e4f9f4fe1c8aa755cea4aa44a654a48a69bd4e06;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/threads/threads.pm b/ext/threads/threads.pm index 6fcd431..2970321 100755 --- a/ext/threads/threads.pm +++ b/ext/threads/threads.pm @@ -1,192 +1,927 @@ package threads; -use 5.7.2; +use 5.008; + use strict; use warnings; -use overload - '==' => \&equal, - 'fallback' => 1; +our $VERSION = '1.38'; +my $XS_VERSION = $VERSION; +$VERSION = eval $VERSION; -#use threads::Shared; BEGIN { - warn "Warning, threads::shared has already been loaded. ". - "To enable shared variables for these modules 'use threads' ". - "must be called before any of those modules are loaded\n" - if($threads::shared::threads_shared); + # Verify this Perl supports threads + use Config; + if (! $Config{useithreads}) { + die("This Perl not built to support threads\n"); + } + + # Declare that we have been loaded + $threads::threads = 1; + + # Complain if 'threads' is loaded after 'threads::shared' + if ($threads::shared::threads_shared) { + warn <<'_MSG_'; +Warning, threads::shared has already been loaded. To +enable shared variables, 'use threads' must be called +before threads::shared or any module that uses it. +_MSG_ + } } -require Exporter; -require DynaLoader; -our @ISA = qw(Exporter DynaLoader); +# Load the XS code +require XSLoader; +XSLoader::load('threads', $XS_VERSION); -our %EXPORT_TAGS = ( all => [qw()]); -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +### Export ### -our @EXPORT = qw( - -); -our $VERSION = '0.05'; +sub import +{ + my $class = shift; # Not used + + # Exported subroutines + my @EXPORT = qw(async); + + # Handle args + while (my $sym = shift) { + if ($sym =~ /^stack/i) { + threads->set_stack_size(shift); + + } elsif ($sym =~ /^exit/i) { + my $flag = shift; + $threads::thread_exit_only = $flag =~ /^thread/i; + + } elsif ($sym =~ /all/) { + push(@EXPORT, qw(yield)); + + } else { + push(@EXPORT, $sym); + } + } + # Export subroutine names + my $caller = caller(); + foreach my $sym (@EXPORT) { + no strict 'refs'; + *{$caller.'::'.$sym} = \&{$sym}; + } -sub equal { - return 1 if($_[0]->tid() == $_[1]->tid()); - return 0; + # Set stack size via environment variable + if (exists($ENV{'PERL5_ITHREADS_STACK_SIZE'})) { + threads->set_stack_size($ENV{'PERL5_ITHREADS_STACK_SIZE'}); + } } -$threads::threads = 1; -bootstrap threads $VERSION; +### Methods, etc. ### -# why document 'new' then use 'create' in the tests! -*create = \&new; +# Exit from a thread (only) +sub exit +{ + my ($class, $status) = @_; + if (! defined($status)) { + $status = 0; + } -# Preloaded methods go here. + # Class method only + if (ref($class)) { + require Carp; + Carp::croak("Usage: threads->exit(status)"); + } + + $class->set_thread_exit_only(1); + CORE::exit($status); +} + +# 'Constant' args for threads->list() +sub threads::all { } +sub threads::running { 1 } +sub threads::joinable { 0 } + +# 'new' is an alias for 'create' +*new = \&create; + +# 'async' is a function alias for the 'threads->create()' method +sub async (&;@) +{ + unshift(@_, 'threads'); + # Use "goto" trick to avoid pad problems from 5.8.1 (fixed in 5.8.2) + goto &create; +} + +# Thread object equality checking +use overload ( + '==' => \&equal, + '!=' => sub { ! equal(@_) }, + 'fallback' => 1 +); 1; + __END__ =head1 NAME -threads - Perl extension allowing use of interpreter based threads from perl +threads - Perl interpreter-based threads + +=head1 VERSION + +This document describes threads version 1.38 =head1 SYNOPSIS -use threads; + use threads ('yield', 'stack_size' => 64*4096, 'exit' => 'threads_only'); -sub start_thread { - print "Thread started\n"; -} + sub start_thread { + my @args = @_; + print('Thread started: ', join(' ', @args), "\n"); + } + my $thread = threads->create('start_thread', 'argument'); + $thread->join(); + + threads->create(sub { print("I am a thread\n"); })->join(); + + my $thread3 = async { foreach (@files) { ... } }; + $thread3->join(); + + # Invoke thread in list context (implicit) so it can return a list + my ($thr) = threads->create(sub { return (qw/a b c/); }); + # or specify list context explicitly + my $thr = threads->create({'context' => 'list'}, + sub { return (qw/a b c/); }); + my @results = $thr->join(); -my $thread = threads->create("start_thread","argument"); + $thread->detach(); -$thread->create(sub { print "I am a thread"},"argument"); + # Get a thread's object + $thread = threads->self(); + $thread = threads->object($tid); -$thread->join(); + # Get a thread's ID + $tid = threads->tid(); + $tid = threads->self->tid(); + $tid = $thread->tid(); -$thread->detach(); + # Give other threads a chance to run + threads->yield(); + yield(); -$thread = threads->self(); + # Lists of non-detached threads + my @threads = threads->list(); + my $thread_count = threads->list(); -threads->tid(); -threads->self->tid(); + my @running = threads->list(threads::running); + my @joinable = threads->list(threads::joinable); -$thread->tid(); + # Test thread objects + if ($thr1 == $thr2) { + ... + } + + # Manage thread stack size + $stack_size = threads->get_stack_size(); + $old_size = threads->set_stack_size(32*4096); + + # Create a thread with a specific context and stack size + my $thr = threads->create({ 'context' => 'list', + 'stack_size' => 32*4096, + 'exit' => 'thread_only' }, + \&foo); + + # Get thread's context + my $wantarray = $thr->wantarray(); + + # Check thread's state + if ($thr->is_running()) { + sleep(1); + } + if ($thr->is_joinable()) { + $thr->join(); + } + + # Send a signal to a thread + $thr->kill('SIGUSR1'); + + # Exit a thread + threads->exit(); =head1 DESCRIPTION -Perl 5.6 introduced something called interpreter threads. Interpreter -threads are different from "5005threads" (the thread model of Perl -5.005) by creating a new perl interpreter per thread and not sharing -any data or state between threads. +Perl 5.6 introduced something called interpreter threads. Interpreter threads +are different from I<5005threads> (the thread model of Perl 5.005) by creating +a new Perl interpreter per thread, and not sharing any data or state between +threads by default. -Prior to perl 5.8 this has only been available to people embedding -perl and for emulating fork() on windows. +Prior to Perl 5.8, this has only been available to people embedding Perl, and +for emulating fork() on Windows. -The threads API is loosely based on the old Thread.pm API. It is very -important to note that variables are not shared between threads, all -variables are per default thread local. To use shared variables one -must use threads::shared. +The I API is loosely based on the old Thread.pm API. It is very +important to note that variables are not shared between threads, all variables +are by default thread local. To use shared variables one must use +L. -It is also important to note that you preferably enable threads by -doing C as early as possible and that it is not possible -to enable threading inside an eval ""; In particular, if you are -intending to share variables with threads::shared, you must -C before you C and threads will emit -a warning if you do it the other way around. +It is also important to note that you must enable threads by doing C as early as possible in the script itself, and that it is not +possible to enable threading inside an C, C, C, or +C. In particular, if you are intending to share variables with +L, you must C before you C. +(C will emit a warning if you do it the other way around.) =over -=item $thread = threads->create(function, LIST) +=item $thr = threads->create(FUNCTION, ARGS) + +This will create a new thread that will begin execution with the specified +entry point function, and give it the I list as parameters. It will +return the corresponding threads object, or C if thread creation failed. + +I may either be the name of a function, an anonymous subroutine, or +a code ref. + + my $thr = threads->create('func_name', ...); + # or + my $thr = threads->create(sub { ... }, ...); + # or + my $thr = threads->create(\&func, ...); + +The C<-Enew()> method is an alias for C<-Ecreate()>. + +=item $thr->join() + +This will wait for the corresponding thread to complete its execution. When +the thread finishes, C<-Ejoin()> will return the return value(s) of the +entry point function. + +The context (void, scalar or list) for the return value(s) for C<-Ejoin()> +is determined at the time of thread creation. + + # Create thread in list context (implicit) + my ($thr1) = threads->create(sub { + my @results = qw(a b c); + return (@results); + }); + # or (explicit) + my $thr1 = threads->create({'context' => 'list'}, + sub { + my @results = qw(a b c); + return (@results); + }); + # Retrieve list results from thread + my @res1 = $thr1->join(); + + # Create thread in scalar context (implicit) + my $thr2 = threads->create(sub { + my $result = 42; + return ($result); + }); + # Retrieve scalar result from thread + my $res2 = $thr2->join(); + + # Create a thread in void context (explicit) + my $thr3 = threads->create({'void' => 1}, + sub { print("Hello, world\n"); }); + # Join the thread in void context (i.e., no return value) + $thr3->join(); + +See L for more details. + +If the program exits without all threads having either been joined or +detached, then a warning will be issued. + +Calling C<-Ejoin()> or C<-Edetach()> on an already joined thread will +cause an error to be thrown. + +=item $thr->detach() + +Makes the thread unjoinable, and causes any eventual return value to be +discarded. When the program exits, any detached threads that are still +running are silently terminated. + +If the program exits without all threads having either been joined or +detached, then a warning will be issued. + +Calling C<-Ejoin()> or C<-Edetach()> on an already detached thread +will cause an error to be thrown. + +=item threads->detach() + +Class method that allows a thread to detach itself. + +=item threads->self() + +Class method that allows a thread to obtain its own I object. + +=item $thr->tid() + +Returns the ID of the thread. Thread IDs are unique integers with the main +thread in a program being 0, and incrementing by 1 for every thread created. + +=item threads->tid() + +Class method that allows a thread to obtain its own ID. + +=item threads->object($tid) + +This will return the I object for the I thread associated +with the specified thread ID. Returns C if there is no thread +associated with the TID, if the thread is joined or detached, if no TID is +specified or if the specified TID is undef. + +=item threads->yield() + +This is a suggestion to the OS to let this thread yield CPU time to other +threads. What actually happens is highly dependent upon the underlying +thread implementation. + +You may do C, and then just use C in your +code. + +=item threads->list() + +=item threads->list(threads::all) -This will create a new thread with the entry point function and give -it LIST as parameters. It will return the corresponding threads -object. +=item threads->list(threads::running) -=item $thread->join +=item threads->list(threads::joinable) -This will wait for the corresponding thread to join. When it finishes -join will return the return values of the entry point function. If a -thread has been detached, join will return without wait. +With no arguments (or using C) and in a list context, returns a +list of all non-joined, non-detached I objects. In a scalar context, +returns a count of the same. -=item $thread->detach +With a I argument (using C), returns a list of all +non-detached I objects that are still running. -Will throw away the return value from the thread and make it -non-joinable. +With a I argument (using C), returns a list of all +non-joined, non-detached I objects that have finished running (i.e., +for which C<-Ejoin()> will not I). -=item threads->self +=item $thr1->equal($thr2) -This will return the object for the current thread. +Tests if two threads objects are the same thread or not. This is overloaded +to the more natural forms: -=item $thread->tid + if ($thr1 == $thr2) { + print("Threads are the same\n"); + } + # or + if ($thr1 != $thr2) { + print("Threads differ\n"); + } -This will return the id of the thread. threads->self->tid() is a -quick way to get current thread id. +(Thread comparison is based on thread IDs.) + +=item async BLOCK; + +C creates a thread to execute the block immediately following +it. This block is treated as an anonymous subroutine, and so must have a +semi-colon after the closing brace. Like Ccreate()>, C +returns a I object. + +=item $thr->_handle() + +This I method returns the memory location of the internal thread +structure associated with a threads object. For Win32, this is a pointer to +the C value returned by C (i.e., C); for other +platforms, it is a pointer to the C structure used in the +C call (i.e., C). + +This method is of no use for general Perl threads programming. Its intent is +to provide other (XS-based) thread modules with the capability to access, and +possibly manipulate, the underlying thread structure associated with a Perl +thread. + +=item threads->_handle() + +Class method that allows a thread to obtain its own I. =back -=head1 WARNINGS +=head1 EXITING A THREAD -=over 4 +The usual method for terminating a thread is to +L from the entry point function with the +appropriate return value(s). + +=over + +=item threads->exit() + +If needed, a thread can be exited at any time by calling +Cexit()>. This will cause the thread to return C in a +scalar context, or the empty list in a list context. + +When called from the I
thread, this behaves the same as C. + +=item threads->exit(status) + +When called from a thread, this behaves like Cexit()> (i.e., the +exit status code is ignored). + +When called from the I
thread, this behaves the same as C. + +=item die() + +Calling C in a thread indicates an abnormal exit for the thread. Any +C<$SIG{__DIE__}> handler in the thread will be called first, and then the +thread will exit with a warning message that will contain any arguments passed +in the C call. + +=item exit(status) + +Calling L inside a thread causes the whole +application to terminate. Because of this, the use of C inside +threaded code, or in modules that might be used in threaded applications, is +strongly discouraged. + +If C really is needed, then consider using the following: + + threads->exit() if threads->can('exit'); # Thread friendly + exit(status); + +=item use threads 'exit' => 'thread_only' + +This globally overrides the default behavior of calling C inside a +thread, and effectively causes such calls to behave the same as +Cexit()>. In other words, with this setting, calling C +causes only the thread to terminate. + +Because of its global effect, this setting should not be used inside modules +or the like. + +The I
thread is unaffected by this setting. + +=item threads->create({'exit' => 'thread_only'}, ...) + +This overrides the default behavior of C inside the newly created +thread only. + +=item $thr->set_thread_exit_only(boolean) + +This can be used to change the I behavior for a thread after +it has been created. With a I argument, C will cause the only +the thread to exit. With a I argument, C will terminate the +application. -=item Cleanup skipped %d active threads +The I
thread is unaffected by this call. -The main thread exited while there were still other threads running. -This is not a good sign: you should either explicitly join the -threads, or let the threads detach themselves, or somehow be certain -that all the non-main threads have finished. +=item threads->set_thread_exit_only(boolean) + +Class method for use inside a thread to changes its own behavior for +C. + +The I
thread is unaffected by this call. =back -=head1 TODO +=head1 THREAD STATE + +The following boolean methods are useful in determining the I of a +thread. =over -=item Fix so the return value is returned when you join. +=item $thr->is_running() + +Returns true if a thread is still running (i.e., if its entry point function +has not yet finished/exited). + +=item $thr->is_joinable() + +Returns true if the thread has finished running, is not detached and has not +yet been joined. In other works, the thread is ready to be joined and will +not I. + +=item $thr->is_detached() + +Returns true if the thread has been detached. -=item Add join_all. +=item threads->is_detached() -=item Fix memory leaks! +Class method that allows a thread to determine whether or not it is detached. =back -=head1 AUTHOR and COPYRIGHT +=head1 THREAD CONTEXT -Arthur Bergman Earthur at contiller.seE +As with subroutines, the type of value returned from a thread's entry point +function may be determined by the thread's I: list, scalar or void. +The thread's context is determined at thread creation. This is necessary so +that the context is available to the entry point function via +L. The thread may then specify a value of +the appropriate type to be returned from C<-Ejoin()>. -threads is released under the same license as Perl. +=head2 Explicit context -Thanks to +Because thread creation and thread joining may occur in different contexts, it +may be desirable to state the context explicitly to the thread's entry point +function. This may be done by calling C<-Ecreate()> with a parameter hash +as the first argument: -Richard Soderberg Ers at crystalflame.netE -Helping me out tons, trying to find reasons for races and other weird bugs! + my $thr = threads->create({'context' => 'list'}, \&foo); + ... + my @results = $thr->join(); -Simon Cozens Esimon at brecon.co.ukE -Being there to answer zillions of annoying questions +In the above, the threads object is returned to the parent thread in scalar +context, and the thread's entry point function C will be called in list +context such that the parent thread can receive a list from the C<-Ejoin()> +call. Similarly, if you need the threads object, but your thread will not be +returning a value (i.e., I context), you would do the following: + + my $thr = threads->create({'context' => 'void'}, \&foo); + ... + $thr->join(); + +The context type may also be used as the I in the parameter hash followed +by a I value: + + threads->create({'scalar' => 1}, \&foo); + ... + my ($thr) = threads->list(); + my $result = $thr->join(); + +=head2 Implicit context + +If not explicitly stated, the thread's context is implied from the context +of the C<-Ecreate()> call: + + # Create thread in list context + my ($thr) = threads->create(...); + + # Create thread in scalar context + my $thr = threads->create(...); + + # Create thread in void context + threads->create(...); + +=head2 $thr->wantarray() + +This returns the thread's context in the same manner as +L. + +=head2 threads->wantarray() + +Class method to return the current thread's context. This is the same as +running L in the current thread. + +=head1 THREAD STACK SIZE + +The default per-thread stack size for different platforms varies +significantly, and is almost always far more than is needed for most +applications. On Win32, Perl's makefile explicitly sets the default stack to +16 MB; on most other platforms, the system default is used, which again may be +much larger than is needed. + +By tuning the stack size to more accurately reflect your application's needs, +you may significantly reduce your application's memory usage, and increase the +number of simultaneously running threads. + +N.B., on Windows, Address space allocation granularity is 64 KB, therefore, +setting the stack smaller than that on Win32 Perl will not save any more +memory. + +=over + +=item threads->get_stack_size(); -Rocco Caputo Etroc at netrus.netE +Returns the current default per-thread stack size. The default is zero, which +means the system default stack size is currently in use. -Vipul Ved Prakash Email at vipul.netE -Helping with debugging. +=item $size = $thr->get_stack_size(); -please join perl-ithreads@perl.org for more information +Returns the stack size for a particular thread. A return value of zero +indicates the system default stack size was used for the thread. + +=item $old_size = threads->set_stack_size($new_size); + +Sets a new default per-thread stack size, and returns the previous setting. + +Some platforms have a minimum thread stack size. Trying to set the stack size +below this value will result in a warning, and the minimum stack size will be +used. + +Some Linux platforms have a maximum stack size. Setting too large of a stack +size will cause thread creation to fail. + +If needed, C<$new_size> will be rounded up to the next multiple of the memory +page size (usually 4096 or 8192). + +Threads created after the stack size is set will then either call +C I<(for pthreads platforms)>, or supply the +stack size to C I<(for Win32 Perl)>. + +(Obviously, this call does not affect any currently extant threads.) + +=item use threads ('stack_size' => VALUE); + +This sets the default per-thread stack size at the start of the application. + +=item $ENV{'PERL5_ITHREADS_STACK_SIZE'} + +The default per-thread stack size may be set at the start of the application +through the use of the environment variable C: + + PERL5_ITHREADS_STACK_SIZE=1048576 + export PERL5_ITHREADS_STACK_SIZE + perl -e'use threads; print(threads->get_stack_size(), "\n")' + +This value overrides any C parameter given to C. Its +primary purpose is to permit setting the per-thread stack size for legacy +threaded applications. + +=item threads->create({'stack_size' => VALUE}, FUNCTION, ARGS) + +The stack size an individual threads may also be specified. This may be done +by calling C<-Ecreate()> with a parameter hash as the first argument: + + my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args); + +=item $thr2 = $thr1->create(FUNCTION, ARGS) + +This creates a new thread (C<$thr2>) that inherits the stack size from an +existing thread (C<$thr1>). This is shorthand for the following: + + my $stack_size = $thr1->get_stack_size(); + my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS); + +=back + +=head1 THREAD SIGNALLING + +When safe signals is in effect (the default behavior - see L +for more details), then signals may be sent and acted upon by individual +threads. + +=over 4 + +=item $thr->kill('SIG...'); + +Sends the specified signal to the thread. Signal names and (positive) signal +numbers are the same as those supported by +L. For example, 'SIGTERM', 'TERM' and +(depending on the OS) 15 are all valid arguments to C<-Ekill()>. + +Returns the thread object to allow for method chaining: + + $thr->kill('SIG...')->join(); + +=back + +Signal handlers need to be set up in the threads for the signals they are +expected to act upon. Here's an example for I a thread: + + use threads; + + sub thr_func + { + # Thread 'cancellation' signal handler + $SIG{'KILL'} = sub { threads->exit(); }; + + ... + } + + # Create a thread + my $thr = threads->create('thr_func'); + + ... + + # Signal the thread to terminate, and then detach + # it so that it will get cleaned up automatically + $thr->kill('KILL')->detach(); + +Here's another simplistic example that illustrates the use of thread +signalling in conjunction with a semaphore to provide rudimentary I +and I capabilities: + + use threads; + use Thread::Semaphore; + + sub thr_func + { + my $sema = shift; + + # Thread 'suspend/resume' signal handler + $SIG{'STOP'} = sub { + $sema->down(); # Thread suspended + $sema->up(); # Thread resumes + }; + + ... + } + + # Create a semaphore and send it to a thread + my $sema = Thread::Semaphore->new(); + my $thr = threads->create('thr_func', $sema); + + # Suspend the thread + $sema->down(); + $thr->kill('STOP'); + + ... + + # Allow the thread to continue + $sema->up(); + +CAVEAT: The thread signalling capability provided by this module does not +actually send signals via the OS. It I signals at the Perl-level +such that signal handlers are called in the appropriate thread. For example, +sending C<$thr-Ekill('STOP')> does not actually suspend a thread (or the +whole process), but does cause a C<$SIG{'STOP'}> handler to be called in that +thread (as illustrated above). + +As such, signals that would normally not be appropriate to use in the +C command (e.g., C) are okay to use with the +C<-Ekill()> method (again, as illustrated above). + +Correspondingly, sending a signal to a thread does not disrupt the operation +the thread is currently working on: The signal will be acted upon after the +current operation has completed. For instance, if the thread is I on +an I/O call, sending it a signal will not cause the I/O call to be interrupted +such that the signal is acted up immediately. + +Sending a signal to a terminated thread is ignored. + +=head1 WARNINGS + +=over 4 + +=item Perl exited with active threads: + +If the program exits without all threads having either been joined or +detached, then this warning will be issued. + +NOTE: If the I
thread exits, then this warning cannot be suppressed +using C as suggested below. + +=item Thread creation failed: pthread_create returned # + +See the appropriate I page for C to determine the actual +cause for the failure. + +=item Thread # terminated abnormally: ... + +A thread terminated in some manner other than just returning from its entry +point function. For example, the thread may have terminated using C. + +=item Using minimum thread stack size of # + +Some platforms have a minimum thread stack size. Trying to set the stack size +below this value will result in the above warning, and the stack size will be +set to the minimum. + +=item Thread creation failed: pthread_attr_setstacksize(I) returned 22 + +The specified I exceeds the system's maximum stack size. Use a smaller +value for the stack size. + +=back + +If needed, thread warnings can be suppressed by using: + + no warnings 'threads'; + +in the appropriate scope. + +=head1 ERRORS + +=over 4 + +=item This Perl not built to support threads + +The particular copy of Perl that you're trying to use was not built using the +C configuration option. + +Having threads support requires all of Perl and all of the XS modules in the +Perl installation to be rebuilt; it is not just a question of adding the +L module (i.e., threaded and non-threaded Perls are binary +incompatible.) + +=item Cannot change stack size of an existing thread + +The stack size of currently extant threads cannot be changed, therefore, the +following results in the above error: + + $thr->set_stack_size($size); + +=item Cannot signal threads without safe signals + +Safe signals must be in effect to use the C<-Ekill()> signalling method. +See L for more details. + +=item Unrecognized signal name: ... + +The particular copy of Perl that you're trying to use does not support the +specified signal being used in a C<-Ekill()> call. + +=back =head1 BUGS =over -=item creating a thread from within a thread is unsafe under win32 +=item Parent-child threads -=item PERL_OLD_SIGNALS are not threadsafe, will not be. +On some platforms, it might not be possible to destroy I threads while +there are still existing I threads. + +=item Creating threads inside special blocks + +Creating threads inside C, C or C blocks should not be +relied upon. Depending on the Perl version and the application code, results +may range from success, to (apparently harmless) warnings of leaked scalar, or +all the way up to crashing of the Perl interpreter. + +=item Unsafe signals + +Since Perl 5.8.0, signals have been made safer in Perl by postponing their +handling until the interpreter is in a I state. See +L and L +for more details. + +Safe signals is the default behavior, and the old, immediate, unsafe +signalling behavior is only in effect in the following situations: + +=over 4 +=item * Perl was been built with C (see C). + +=item * The environment variable C is set to C (see L). + +=item * The module L is used. =back +If unsafe signals is in effect, then signal handling is not thread-safe, and +the C<-Ekill()> signalling method cannot be used. + +=item Returning closures from threads + +Returning closures from threads should not be relied upon. Depending of the +Perl version and the application code, results may range from success, to +(apparently harmless) warnings of leaked scalar, or all the way up to crashing +of the Perl interpreter. + +=item Perl Bugs and the CPAN Version of L + +Support for threads extents beyond the code in this module (i.e., +F and F), and into the Perl iterpreter itself. Older +versions of Perl contain bugs that may manifest themselves despite using the +latest version of L from CPAN. There is no workaround for this other +than upgrading to the lastest version of Perl. + +(Before you consider posting a bug report, please consult, and possibly post a +message to the discussion forum to see if what you've encountered is a known +problem.) + +=back + +=head1 REQUIREMENTS + +Perl 5.8.0 or later + =head1 SEE ALSO -L, L, L, L, L +L Discussion Forum on CPAN: +L + +Annotated POD for L: +L + +L, L + +L and +L + +Perl threads mailing list: +L + +Stack size discussion: +L + +=head1 AUTHOR + +Artur Bergman Esky AT crucially DOT netE + +threads is released under the same license as Perl. + +CPAN version produced by Jerry D. Hedden + +=head1 ACKNOWLEDGEMENTS + +Richard Soderberg Eperl AT crystalflame DOT netE - +Helping me out tons, trying to find reasons for races and other weird bugs! + +Simon Cozens Esimon AT brecon DOT co DOT ukE - +Being there to answer zillions of annoying questions + +Rocco Caputo Etroc AT netrus DOT netE + +Vipul Ved Prakash Email AT vipul DOT netE - +Helping with debugging + +Dean Arnold Edarnold AT presicient DOT comE - +Stack size API =cut