use strict;
use warnings;
-our $VERSION = '1.28';
+our $VERSION = '1.36';
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
### Methods, etc. ###
+# Our own exit function/method
+sub exit
+{
+ CORE::exit(0);
+}
+
+# 'Constant' args for threads->list()
+sub threads::all { }
+sub threads::running { 1 }
+sub threads::joinable { 0 }
+
# 'new' is an alias for 'create'
*new = \&create;
=head1 VERSION
-This document describes threads version 1.28
+This document describes threads version 1.36
=head1 SYNOPSIS
sub start_thread {
my @args = @_;
- print "Thread started: @args\n";
+ print('Thread started: ', join(' ', @args), "\n");
}
my $thread = threads->create('start_thread', 'argument');
$thread->join();
my $thread3 = async { foreach (@files) { ... } };
$thread3->join();
- # Invoke thread in list context so it can return a list
+ # 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();
$thread->detach();
my @threads = threads->list();
my $thread_count = threads->list();
+ my @running = threads->list(threads::running);
+ my @joinable = threads->list(threads::joinable);
+
if ($thr1 == $thr2) {
...
}
$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 },
+ \&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();
+ }
+
$thr->kill('SIGUSR1');
+ threads->exit();
+
=head1 DESCRIPTION
Perl 5.6 introduced something called interpreter threads. Interpreter threads
# or
my $thr = threads->create(\&func, ...);
-The thread may be created in I<list> context, or I<scalar> context as follows:
-
- # Create thread in list context
- my ($thr) = threads->create(...);
-
- # Create thread in scalar context
- my $thr = threads->create(...);
-
-This has consequences for the C<-E<gt>join()> method describe below.
-
-Although a thread may be created in I<void> context, to do so you must
-I<chain> either the C<-E<gt>join()> or C<-E<gt>detach()> method to the
-C<-E<gt>create()> call:
-
- threads->create(...)->join();
-
The C<-E<gt>new()> method is an alias for C<-E<gt>create()>.
=item $thr->join()
the thread finishes, C<-E<gt>join()> will return the return value(s) of the
entry point function.
-The context (void, scalar or list) of the thread creation is also the
-context for C<-E<gt>join()>. This means that if you intend to return an array
-from a thread, you must use C<my ($thr) = threads->create(...)>, and that
-if you intend to return a scalar, you must use C<my $thr = ...>:
+The context (void, scalar or list) for the return value(s) for C<-E<gt>join()>
+is determined at the time of thread creation.
- # Create thread in list context
+ # 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
+ # 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();
-If the program exits without all other threads having been either joined or
-detached, then a warning will be issued. (A program exits either because one
-of its threads explicitly calls L<exit()|perlfunc/"exit EXPR">, or in the case
-of the main thread, reaches the end of the main program file.)
+ # 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</"THREAD CONTEXT"> for more details.
+
+If the program exits without all threads having either been joined or
+detached, then a warning will be issued.
Calling C<-E<gt>join()> or C<-E<gt>detach()> 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.
+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<-E<gt>join()> or C<-E<gt>detach()> on an already detached thread
will cause an error to be thrown.
Class method that allows a thread to detach itself.
+=item threads->exit()
+
+The usual method for terminating a thread is to
+L<return()|perlfunc/"return EXPR"> from the entry point function with the
+appropriate return value(s).
+
+If needed, a thread can be exited at any time by calling
+C<threads-E<gt>exit()>. This will cause the thread to return C<undef> in a
+scalar context, or the empty list in a list context.
+
+Calling C<die()> 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<die()> call.
+
+Calling C<exit()> in a thread is discouraged, but is equivalent to calling
+C<threads-E<gt>exit()>.
+
+If the desired affect is to truly terminate the application from a thread,
+then use L<POSIX::_exit()|POSIX/"_exit">, if available.
+
=item threads->self()
Class method that allows a thread to obtain its own I<threads> object.
=item threads->list()
-In a list context, returns a list of all non-joined, non-detached I<threads>
-objects. In a scalar context, returns a count of the same.
+=item threads->list(threads::all)
+
+=item threads->list(threads::running)
+
+=item threads->list(threads::joinable)
+
+With no arguments (or using C<threads::all>) and in a list context, returns a
+list of all non-joined, non-detached I<threads> objects. In a scalar context,
+returns a count of the same.
+
+With a I<true> argument (using C<threads::running>), returns a list of all
+non-detached I<threads> objects that are still running.
+
+With a I<false> argument (using C<threads::joinable>), returns a list of all
+non-joined, non-detached I<threads> objects that have finished running (i.e.,
+for which C<-E<gt>join()> will not I<block>).
=item $thr1->equal($thr2)
=back
+=head1 THREAD STATE
+
+The following boolean methods are useful in determining the I<state> of a
+thread.
+
+=over
+
+=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<block>.
+
+=item $thr->is_detached()
+
+Returns true if the thread has been detached.
+
+=item threads->is_detached()
+
+Class method that allows a thread to determine whether or not it is detached.
+
+=back
+
+=head1 THREAD CONTEXT
+
+As with subroutines, the type of value returned from a thread's entry point
+function may be determined by the thread's I<context>: 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<wantarray()|perlfunc/"wantarray">. The thread may then specify a value of
+the appropriate type to be returned from C<-E<gt>join()>.
+
+=head2 Explicit context
+
+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<-E<gt>create()> with a parameter hash
+as the first argument:
+
+ my $thr = threads->create({'context' => 'list'}, \&foo);
+ ...
+ my @results = $thr->join();
+
+In the above, the threads object is returned to the parent thread in scalar
+context, and the thread's entry point function C<foo> will be called in list
+context such that the parent thread can receive a list from the C<-E<gt>join()>
+call. Similarly, if you need the threads object, but your thread will not be
+returning a value (i.e., I<void> 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<key> in the parameter hash followed
+by a I<true> 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<-E<gt>create()> 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<wantarray()|perlfunc/"wantarray">.
+
+=head2 threads->wantarray()
+
+Class method to return the current thread's context. This is the same as
+running L<wantarray()|perlfunc/"wantarray"> in the current thread.
+
=head1 THREAD STACK SIZE
The default per-thread stack size for different platforms varies
=item threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)
-This change to the thread creation method permits specifying the stack size
-for an individual thread.
+The stack size an individual threads may also be specified. This may be done
+by calling C<-E<gt>create()> with a parameter hash as the first argument:
+
+ my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
=item $thr2 = $thr1->create(FUNCTION, ARGS)
=head1 THREAD SIGNALLING
-When safe signals is in effect (the default behavior - see L<Unsafe signals>
+When safe signals is in effect (the default behavior - see L</"Unsafe signals">
for more details), then signals may be sent and acted upon by individual
threads.
use threads;
- # Suppress warning message when thread is 'killed'
- no warnings 'threads';
-
sub thr_func
{
# Thread 'cancellation' signal handler
- $SIG{'KILL'} = sub { die("Thread killed\n"); };
+ $SIG{'KILL'} = sub { threads->exit(); };
...
}
=over 4
-=item A thread exited while # other threads were still running
+=item Perl exited with active threads:
-A thread (not necessarily the main thread) exited while there were still other
-threads running. Usually, it's a good idea to first collect the return values
-of the created threads by joining them, and only then exit from the main
-thread.
+If the program exits without all threads having either been joined or
+detached, then this warning will be issued.
+
+NOTE: This warning cannot be suppressed using C<no warnings 'threads';> as
+suggested below.
=item Thread creation failed: pthread_create returned #
=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 exited via C<die>.
+point function. For example, the thread may have terminated using C<die>.
=item Using minimum thread stack size of #
$thr->set_stack_size($size);
-=item Cannot signal other threads without safe signals
+=item Cannot signal threads without safe signals
Safe signals must be in effect to use the C<-E<gt>kill()> signalling method.
-See L<Unsafe signals> for more details.
+See L</"Unsafe signals"> for more details.
=item Unrecognized signal name: ...
=item Creating threads inside special blocks
-Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks cannot 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
-attempts to free unreferenced scalars, all the way up to crashing of the Perl
-interpreter.
+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
=item Returning closures from threads
-Returning closures from threads cannot be relied upon. Depending of the Perl
-version and the application code, results may range from success, to
-(apparently harmless) warnings of leaked scalar, all the way up to crashing of
-the Perl interpreter.
+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<threads>
L<http://www.cpanforum.com/dist/threads>
Annotated POD for L<threads>:
-L<http://annocpan.org/~JDHEDDEN/threads-1.28/shared.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-1.36/threads.pm>
L<threads::shared>, L<perlthrtut>