use strict;
use warnings;
-our $VERSION = '1.81';
+our $VERSION = '2.20'; # remember to update version in POD!
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
=head1 VERSION
-This document describes threads version 1.81
+This document describes threads version 2.20
+
+=head1 WARNING
+
+The "interpreter-based threads" provided by Perl are not the fast, lightweight
+system for multitasking that one might expect or hope for. Threads are
+implemented in a way that make them easy to misuse. Few people know how to
+use them correctly or will be able to provide help.
+
+The use of interpreter-based threads in perl is officially
+L<discouraged|perlpolicy/discouraged>.
=head1 SYNOPSIS
use threads qw(stringify);
my $thr = threads->create(...);
- print("Thread $thr started...\n"); # Prints out: Thread 1 started...
+ print("Thread $thr started\n"); # Prints: Thread 1 started
=item threads->object($tid)
=item $thr->_handle()
-This I<private> method returns the memory location of the internal thread
-structure associated with a threads object. For Win32, this is a pointer to
-the C<HANDLE> value returned by C<CreateThread> (i.e., C<HANDLE *>); for other
-platforms, it is a pointer to the C<pthread_t> structure used in the
-C<pthread_create> call (i.e., C<pthread_t *>).
+This I<private> method returns a pointer (i.e., the memory location expressed
+as an unsigned integer) to the internal thread structure associated with a
+threads object. For Win32, this is a pointer to the C<HANDLE> value returned
+by C<CreateThread> (i.e., C<HANDLE *>); for other platforms, it is a pointer
+to the C<pthread_t> structure used in the C<pthread_create> call (i.e.,
+C<pthread_t *>).
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
To specify a particular stack size for any individual thread, call
C<-E<gt>create()> with a hash reference as the first argument:
- my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
+ my $thr = threads->create({'stack_size' => 32*4096},
+ \&foo, @args);
=item $thr2 = $thr1->create(FUNCTION, ARGS)
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);
+ my $thr2 = threads->create({'stack_size' => $stack_size},
+ FUNCTION, ARGS);
=back
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.
+Sending a signal to a terminated/finished thread is ignored.
=head1 WARNINGS
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<threads> module (i.e., threaded and non-threaded Perls are binary
-incompatible.)
+incompatible).
=item Cannot change stack size of an existing thread
On MSWin32, each thread maintains its own set of environment variables.
+=item Catching signals
+
+Signals are I<caught> by the main thread (thread ID = 0) of a script.
+Therefore, setting up signal handlers in threads for purposes other than
+L</"THREAD SIGNALLING"> as documented above will not accomplish what is
+intended.
+
+This is especially true if trying to catch C<SIGALRM> in a thread. To handle
+alarms in threads, set up a signal handler in the main thread, and then use
+L</"THREAD SIGNALLING"> to relay the signal to the thread:
+
+ # Create thread with a task that may time out
+ my $thr = threads->create(sub {
+ threads->yield();
+ eval {
+ $SIG{ALRM} = sub { die("Timeout\n"); };
+ alarm(10);
+ ... # Do work here
+ alarm(0);
+ };
+ if ($@ =~ /Timeout/) {
+ warn("Task in thread timed out\n");
+ }
+ };
+
+ # Set signal handler to relay SIGALRM to thread
+ $SIG{ALRM} = sub { $thr->kill('ALRM') };
+
+ ... # Main thread continues working
+
=item Parent-child threads
On some platforms, it might not be possible to destroy I<parent> threads while
there are still existing I<child> threads.
-=item Creating threads inside special blocks
-
-Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> 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
=item * Perl has been built with C<PERL_OLD_SIGNALS> (see C<perl -V>).
-=item * The environment variable C<PERL_SIGNALS> is set to C<unsafe> (see L<perlrun/"PERL_SIGNALS">).
+=item * The environment variable C<PERL_SIGNALS> is set to C<unsafe>
+(see L<perlrun/"PERL_SIGNALS">).
=item * The module L<Perl::Unsafe::Signals> is used.
If unsafe signals is in effect, then signal handling is not thread-safe, and
the C<-E<gt>kill()> signalling method cannot be used.
-=item Returning closures from threads
+=item Identity of objects returned from threads
+
+When a value is returned from a thread through a C<join> operation,
+the value and everything that it references is copied across to the
+joining thread, in much the same way that values are copied upon thread
+creation. This works fine for most kinds of value, including arrays,
+hashes, and subroutines. The copying recurses through array elements,
+reference scalars, variables closed over by subroutines, and other kinds
+of reference.
-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.
+However, everything referenced by the returned value is a fresh copy in
+the joining thread, even if a returned object had in the child thread
+been a copy of something that previously existed in the parent thread.
+After joining, the parent will therefore have a duplicate of each such
+object. This sometimes matters, especially if the object gets mutated;
+this can especially matter for private data to which a returned subroutine
+provides access.
-=item Returning objects from threads
+=item Returning blessed objects from threads
-Returning objects from threads does not work. Depending on the classes
+Returning blessed objects from threads does not work. Depending on the classes
involved, you may be able to work around this by returning a serialized
version of the object (e.g., using L<Data::Dumper> or L<Storable>), and then
reconstituting it in the joining thread. If you're using Perl 5.10.0 or
=item Open directory handles
-Spawning threads with open directory handles (see
-L<opendir|perlfunc/"opendir DIRHANDLE,EXPR">) will crash the interpreter.
+In perl 5.14 and higher, on systems other than Windows that do
+not support the C<fchdir> C function, directory handles (see
+L<opendir|perlfunc/"opendir DIRHANDLE,EXPR">) will not be copied to new
+threads. You can use the C<d_fchdir> variable in L<Config.pm|Config> to
+determine whether your system supports it.
+
+In prior perl versions, spawning threads with open directory handles would
+crash the interpreter.
L<[perl #75154]|http://rt.perl.org/rt3/Public/Bug/Display.html?id=75154>
+=item Detached threads and global destruction
+
+If the main thread exits while there are detached threads which are still
+running, then Perl's global destruction phase is not executed because
+otherwise certain global structures that control the operation of threads and
+that are allocated in the main thread's memory may get destroyed before the
+detached thread is destroyed.
+
+If you are using any code that requires the execution of the global
+destruction phase for clean up (e.g., removing temp files), then do not use
+detached threads, but rather join all threads before exiting the program.
+
=item Perl Bugs and the CPAN Version of L<threads>
Support for threads extends beyond the code in this module (i.e.,
=head1 SEE ALSO
-L<threads> Discussion Forum on CPAN:
-L<http://www.cpanforum.com/dist/threads>
+threads on MetaCPAN:
+L<https://metacpan.org/release/threads>
-Annotated POD for L<threads>:
-L<http://annocpan.org/~JDHEDDEN/threads-1.81/threads.pm>
-
-Source repository:
-L<http://code.google.com/p/threads-shared/>
+Code repository for CPAN distribution:
+L<https://github.com/Dual-Life/threads>
L<threads::shared>, L<perlthrtut>
L<http://www.perl.com/pub/a/2002/09/04/threads.html>
Perl threads mailing list:
-L<http://lists.cpan.org/showlist.cgi?name=iThreads>
+L<http://lists.perl.org/list/ithreads.html>
Stack size discussion:
L<http://www.perlmonks.org/?node_id=532956>
+Sample code in the I<examples> directory of this distribution on CPAN.
+
=head1 AUTHOR
Artur Bergman E<lt>sky AT crucially DOT netE<gt>