X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/3d1f1caf68f964a756e1ffb5a4c6bc032cad2402..da459ff628f80fa8577abb6f6afc86718eeaeb88:/lib/Thread.pm diff --git a/lib/Thread.pm b/lib/Thread.pm index c9f05c0..247f90c 100644 --- a/lib/Thread.pm +++ b/lib/Thread.pm @@ -1,88 +1,86 @@ package Thread; use strict; +use warnings; +no warnings 'redefine'; -our($VERSION, $ithreads, $othreads); +our $VERSION = '3.02'; +$VERSION = eval $VERSION; BEGIN { - $VERSION = '2.00'; use Config; - $ithreads = $Config{useithreads}; - $othreads = $Config{use5005threads}; + if (! $Config{useithreads}) { + die("This Perl not built to support threads\n"); + } } +use threads 'yield'; +use threads::shared; + require Exporter; -use XSLoader (); -our(@ISA, @EXPORT, @EXPORT_OK); +our @ISA = qw(Exporter threads); +our @EXPORT = qw(cond_wait cond_broadcast cond_signal); +our @EXPORT_OK = qw(async yield); -@ISA = qw(Exporter); +sub async (&;@) { return Thread->new(shift); } -BEGIN { - if ($ithreads) { - @EXPORT = qw(cond_wait cond_broadcast cond_signal) - } elsif ($othreads) { - @EXPORT_OK = qw(cond_signal cond_broadcast cond_wait); - } - push @EXPORT_OK, qw(async yield); -} +sub done { return ! shift->is_running(); } -=head1 NAME +sub eval { die("'eval' not implemented with 'ithreads'\n"); }; +sub flags { die("'flags' not implemented with 'ithreads'\n"); }; + +1; -Thread - manipulate threads in Perl (for old code only) +__END__ + +=head1 NAME -=head1 CAVEAT +Thread - Manipulate threads in Perl (for old code only) -Perl has two thread models. +=head1 DEPRECATED -In Perl 5.005 the thread model was that all data is implicitly shared -and shared access to data has to be explicitly synchronized. -This model is called "5005threads". +The C module served as the frontend to the old-style thread model, +called I<5005threads>, that was introduced in release 5.005. That model was +deprecated, and has been removed in version 5.10. -In Perl 5.6 a new model was introduced in which all is was thread -local and shared access to data has to be explicitly declared. -This model is called "ithreads", for "interpreter threads". +For old code and interim backwards compatibility, the C module has +been reworked to function as a frontend for the new interpreter threads +(I) model. However, some previous functionality is not available. +Further, the data sharing models between the two thread models are completely +different, and anything to do with data sharing has to be thought differently. +With I, you must explicitly C variables between the +threads. -In Perl 5.6 the ithreads model was not available as a public API, -only as an internal API that was available for extension writers, -and to implement fork() emulation on Win32 platforms. +You are strongly encouraged to migrate any existing threaded code to the new +model (i.e., use the C and C modules) as soon as +possible. -In Perl 5.8 the ithreads model became available through the C -module. +=head1 HISTORY -Neither model is configured by default into Perl (except, as mentioned -above, in Win32 ithreads are always available.) You can see your -Perl's threading configuration by running C and looking for -the I variables, or inside script by C -and testing for C<$Config{use5005threads}> and C<$Config{useithreads}>. +In Perl 5.005, the thread model was that all data is implicitly shared, and +shared access to data has to be explicitly synchronized. This model is called +I<5005threads>. -For old code and interim backwards compatibility, the Thread module -has been reworked to function as a frontend for both 5005threads and -ithreads. +In Perl 5.6, a new model was introduced in which all is was thread local and +shared access to data has to be explicitly declared. This model is called +I, for "interpreter threads". -Note that the compatibility is not complete: because the data sharing -models are directly opposed, anything to do with data sharing has to -be thought differently. With the ithreads you must explicitly share() -variables between the threads. +In Perl 5.6, the I model was not available as a public API; only as +an internal API that was available for extension writers, and to implement +fork() emulation on Win32 platforms. -For new code the use of the C module is discouraged and -the direct use of the C and C modules -is encouraged instead. +In Perl 5.8, the I model became available through the C +module, and the I<5005threads> model was deprecated. -Finally, note that there are many known serious problems with the -5005threads, one of the least of which is that regular expression -match variables like $1 are not threadsafe, that is, they easily get -corrupted by competing threads. Other problems include more insidious -data corruption and mysterious crashes. You are seriously urged to -use ithreads instead. +In Perl 5.10, the I<5005threads> model was removed from the Perl interpreter. =head1 SYNOPSIS - use Thread; + use Thread qw(:DEFAULT async yield); my $t = Thread->new(\&start_sub, @start_args); $result = $t->join; - $result = $t->eval; $t->detach; if ($t->done) { @@ -90,28 +88,22 @@ use ithreads instead. } if($t->equal($another_thread)) { - # ... + # ... } yield(); - my $tid = Thread->self->tid; + my $tid = Thread->self->tid; lock($scalar); lock(@array); lock(%hash); - lock(\&sub); # not available with ithreads - - $flags = $t->flags; # not available with ithreads - - my @list = Thread->list; # not available with ithreads - - use Thread 'async'; + my @list = Thread->list; =head1 DESCRIPTION -The C module provides multithreading support for perl. +The C module provides multithreading support for Perl. =head1 FUNCTIONS @@ -149,14 +141,6 @@ elements of that container are not locked. For example, if a thread does a C, any other thread doing a C won't block. -With 5005threads you may also C a sub, using C. -Any calls to that sub from another thread will block until the lock -is released. This behaviour is not equivalent to declaring the sub -with the C attribute. The C attribute serializes -access to a subroutine, but allows different threads non-simultaneous -access. C, on the other hand, will not allow I other -thread access for the duration of the lock. - Finally, C will traverse up references exactly I level. C is equivalent to C, while C is not. @@ -172,6 +156,10 @@ returns a thread object. The Cself> function returns a thread object that represents the thread making the Cself> call. +=item Thread->list + +Returns a list of all non-joined, non-detached Thread objects. + =item cond_wait VARIABLE The C function takes a B variable as @@ -223,12 +211,6 @@ be returned at this time. If you don't want the thread performing the C to die as well, you should either wrap the C in an C or use the C thread method instead of C. -=item eval - -The C method wraps an C around a C, and so waits for -a thread to exit, passing along any values the thread might have returned. -Errors, of course, get placed into C<$@>. (Not available with ithreads.) - =item detach C tells a thread that it is never going to be joined i.e. @@ -236,7 +218,7 @@ that all traces of its existence can be removed once it stops running. Errors in detached threads will not be visible anywhere - if you want to catch them, you should use $SIG{__DIE__} or something like that. -=item equal +=item equal C tests whether two thread objects represent the same thread and returns true if they do. @@ -248,90 +230,44 @@ a monotonically increasing integer assigned when a thread is created. The main thread of a program will have a tid of zero, while subsequent threads will have tids assigned starting with one. -=item flags - -The C method returns the flags for the thread. This is the -integer value corresponding to the internal flags for the thread, -and the value may not be all that meaningful to you. -(Not available with ithreads.) - =item done The C method returns true if the thread you're checking has -finished, and false otherwise. (Not available with ithreads.) +finished, and false otherwise. =back -=head1 LIMITATIONS +=head1 DEFUNCT -The sequence number used to assign tids is a simple integer, and no -checking is done to make sure the tid isn't currently in use. If a -program creates more than 2**32 - 1 threads in a single run, threads -may be assigned duplicate tids. This limitation may be lifted in -a future version of Perl. +The following were implemented with I<5005threads>, but are no longer +available with I. -=head1 SEE ALSO - -L (not available with 5005threads) +=over 8 -L, L, L, -L (not available with ithreads) +=item lock(\&sub) -=cut +With 5005threads, you could also C a sub such that any calls to that sub +from another thread would block until the lock was released. -# -# Methods -# +Also, subroutines could be declared with the C<:locked> attribute which would +serialize access to the subroutine, but allowed different threads +non-simultaneous access. -# -# Exported functions -# +=item eval -sub async (&) { - return Thread->new($_[0]); -} +The C method wrapped an C around a C, and so waited for a +thread to exit, passing along any values the thread might have returned and +placing any errors into C<$@>. -sub eval { - return eval { shift->join; }; -} +=item flags -sub unimplemented { - print $_[0], " unimplemented with ", - $Config{useithreads} ? "ithreads" : "5005threads", "\n"; +The C method returned the flags for the thread - an integer value +corresponding to the internal flags for the thread. -} +=back -sub unimplement { - for my $m (@_) { - no strict 'refs'; - *{"Thread::$m"} = sub { unimplemented $m }; - } -} +=head1 SEE ALSO -BEGIN { - if ($ithreads) { - if ($othreads) { - require Carp; - Carp::croak("This Perl has both ithreads and 5005threads (serious malconfiguration)"); - } - XSLoader::load 'threads'; - for my $m (qw(new join detach yield self tid equal list)) { - no strict 'refs'; - *{"Thread::$m"} = \&{"threads::$m"}; - } - require 'threads/shared.pm'; - for my $m (qw(cond_signal cond_broadcast cond_wait)) { - no strict 'refs'; - *{"Thread::$m"} = \&{"threads::shared::${m}_enabled"}; - } - # trying to unimplement eval gives redefined warning - unimplement(qw(done flags)); - } elsif ($othreads) { - XSLoader::load 'Thread'; - } else { - require Carp; - Carp::croak("This Perl has neither ithreads nor 5005threads"); - } -} +L, L, L, L -1; +=cut