| 1 | package Thread;
|
|---|
| 2 |
|
|---|
| 3 | use strict;
|
|---|
| 4 |
|
|---|
| 5 | our($VERSION, $ithreads, $othreads);
|
|---|
| 6 |
|
|---|
| 7 | BEGIN {
|
|---|
| 8 | $VERSION = '2.00';
|
|---|
| 9 | use Config;
|
|---|
| 10 | $ithreads = $Config{useithreads};
|
|---|
| 11 | $othreads = $Config{use5005threads};
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | require Exporter;
|
|---|
| 15 | use XSLoader ();
|
|---|
| 16 | our(@ISA, @EXPORT, @EXPORT_OK);
|
|---|
| 17 |
|
|---|
| 18 | @ISA = qw(Exporter);
|
|---|
| 19 |
|
|---|
| 20 | BEGIN {
|
|---|
| 21 | if ($ithreads) {
|
|---|
| 22 | @EXPORT = qw(cond_wait cond_broadcast cond_signal)
|
|---|
| 23 | } elsif ($othreads) {
|
|---|
| 24 | @EXPORT_OK = qw(cond_signal cond_broadcast cond_wait);
|
|---|
| 25 | }
|
|---|
| 26 | push @EXPORT_OK, qw(async yield);
|
|---|
| 27 | }
|
|---|
| 28 |
|
|---|
| 29 | =head1 NAME
|
|---|
| 30 |
|
|---|
| 31 | Thread - manipulate threads in Perl (for old code only)
|
|---|
| 32 |
|
|---|
| 33 | =head1 CAVEAT
|
|---|
| 34 |
|
|---|
| 35 | Perl has two thread models.
|
|---|
| 36 |
|
|---|
| 37 | In Perl 5.005 the thread model was that all data is implicitly shared
|
|---|
| 38 | and shared access to data has to be explicitly synchronized.
|
|---|
| 39 | This model is called "5005threads".
|
|---|
| 40 |
|
|---|
| 41 | In Perl 5.6 a new model was introduced in which all is was thread
|
|---|
| 42 | local and shared access to data has to be explicitly declared.
|
|---|
| 43 | This model is called "ithreads", for "interpreter threads".
|
|---|
| 44 |
|
|---|
| 45 | In Perl 5.6 the ithreads model was not available as a public API,
|
|---|
| 46 | only as an internal API that was available for extension writers,
|
|---|
| 47 | and to implement fork() emulation on Win32 platforms.
|
|---|
| 48 |
|
|---|
| 49 | In Perl 5.8 the ithreads model became available through the C<threads>
|
|---|
| 50 | module.
|
|---|
| 51 |
|
|---|
| 52 | Neither model is configured by default into Perl (except, as mentioned
|
|---|
| 53 | above, in Win32 ithreads are always available.) You can see your
|
|---|
| 54 | Perl's threading configuration by running C<perl -V> and looking for
|
|---|
| 55 | the I<use...threads> variables, or inside script by C<use Config;>
|
|---|
| 56 | and testing for C<$Config{use5005threads}> and C<$Config{useithreads}>.
|
|---|
| 57 |
|
|---|
| 58 | For old code and interim backwards compatibility, the Thread module
|
|---|
| 59 | has been reworked to function as a frontend for both 5005threads and
|
|---|
| 60 | ithreads.
|
|---|
| 61 |
|
|---|
| 62 | Note that the compatibility is not complete: because the data sharing
|
|---|
| 63 | models are directly opposed, anything to do with data sharing has to
|
|---|
| 64 | be thought differently. With the ithreads you must explicitly share()
|
|---|
| 65 | variables between the threads.
|
|---|
| 66 |
|
|---|
| 67 | For new code the use of the C<Thread> module is discouraged and
|
|---|
| 68 | the direct use of the C<threads> and C<threads::shared> modules
|
|---|
| 69 | is encouraged instead.
|
|---|
| 70 |
|
|---|
| 71 | Finally, note that there are many known serious problems with the
|
|---|
| 72 | 5005threads, one of the least of which is that regular expression
|
|---|
| 73 | match variables like $1 are not threadsafe, that is, they easily get
|
|---|
| 74 | corrupted by competing threads. Other problems include more insidious
|
|---|
| 75 | data corruption and mysterious crashes. You are seriously urged to
|
|---|
| 76 | use ithreads instead.
|
|---|
| 77 |
|
|---|
| 78 | =head1 SYNOPSIS
|
|---|
| 79 |
|
|---|
| 80 | use Thread;
|
|---|
| 81 |
|
|---|
| 82 | my $t = Thread->new(\&start_sub, @start_args);
|
|---|
| 83 |
|
|---|
| 84 | $result = $t->join;
|
|---|
| 85 | $result = $t->eval;
|
|---|
| 86 | $t->detach;
|
|---|
| 87 |
|
|---|
| 88 | if ($t->done) {
|
|---|
| 89 | $t->join;
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | if($t->equal($another_thread)) {
|
|---|
| 93 | # ...
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | yield();
|
|---|
| 97 |
|
|---|
| 98 | my $tid = Thread->self->tid;
|
|---|
| 99 |
|
|---|
| 100 | lock($scalar);
|
|---|
| 101 | lock(@array);
|
|---|
| 102 | lock(%hash);
|
|---|
| 103 |
|
|---|
| 104 | lock(\&sub); # not available with ithreads
|
|---|
| 105 |
|
|---|
| 106 | $flags = $t->flags; # not available with ithreads
|
|---|
| 107 |
|
|---|
| 108 | my @list = Thread->list; # not available with ithreads
|
|---|
| 109 |
|
|---|
| 110 | use Thread 'async';
|
|---|
| 111 |
|
|---|
| 112 | =head1 DESCRIPTION
|
|---|
| 113 |
|
|---|
| 114 | The C<Thread> module provides multithreading support for perl.
|
|---|
| 115 |
|
|---|
| 116 | =head1 FUNCTIONS
|
|---|
| 117 |
|
|---|
| 118 | =over 8
|
|---|
| 119 |
|
|---|
| 120 | =item $thread = Thread->new(\&start_sub)
|
|---|
| 121 |
|
|---|
| 122 | =item $thread = Thread->new(\&start_sub, LIST)
|
|---|
| 123 |
|
|---|
| 124 | C<new> starts a new thread of execution in the referenced subroutine. The
|
|---|
| 125 | optional list is passed as parameters to the subroutine. Execution
|
|---|
| 126 | continues in both the subroutine and the code after the C<new> call.
|
|---|
| 127 |
|
|---|
| 128 | C<Thread->new> returns a thread object representing the newly created
|
|---|
| 129 | thread.
|
|---|
| 130 |
|
|---|
| 131 | =item lock VARIABLE
|
|---|
| 132 |
|
|---|
| 133 | C<lock> places a lock on a variable until the lock goes out of scope.
|
|---|
| 134 |
|
|---|
| 135 | If the variable is locked by another thread, the C<lock> call will
|
|---|
| 136 | block until it's available. C<lock> is recursive, so multiple calls
|
|---|
| 137 | to C<lock> are safe--the variable will remain locked until the
|
|---|
| 138 | outermost lock on the variable goes out of scope.
|
|---|
| 139 |
|
|---|
| 140 | Locks on variables only affect C<lock> calls--they do I<not> affect normal
|
|---|
| 141 | access to a variable. (Locks on subs are different, and covered in a bit.)
|
|---|
| 142 | If you really, I<really> want locks to block access, then go ahead and tie
|
|---|
| 143 | them to something and manage this yourself. This is done on purpose.
|
|---|
| 144 | While managing access to variables is a good thing, Perl doesn't force
|
|---|
| 145 | you out of its living room...
|
|---|
| 146 |
|
|---|
| 147 | If a container object, such as a hash or array, is locked, all the
|
|---|
| 148 | elements of that container are not locked. For example, if a thread
|
|---|
| 149 | does a C<lock @a>, any other thread doing a C<lock($a[12])> won't
|
|---|
| 150 | block.
|
|---|
| 151 |
|
|---|
| 152 | With 5005threads you may also C<lock> a sub, using C<lock &sub>.
|
|---|
| 153 | Any calls to that sub from another thread will block until the lock
|
|---|
| 154 | is released. This behaviour is not equivalent to declaring the sub
|
|---|
| 155 | with the C<locked> attribute. The C<locked> attribute serializes
|
|---|
| 156 | access to a subroutine, but allows different threads non-simultaneous
|
|---|
| 157 | access. C<lock &sub>, on the other hand, will not allow I<any> other
|
|---|
| 158 | thread access for the duration of the lock.
|
|---|
| 159 |
|
|---|
| 160 | Finally, C<lock> will traverse up references exactly I<one> level.
|
|---|
| 161 | C<lock(\$a)> is equivalent to C<lock($a)>, while C<lock(\\$a)> is not.
|
|---|
| 162 |
|
|---|
| 163 | =item async BLOCK;
|
|---|
| 164 |
|
|---|
| 165 | C<async> creates a thread to execute the block immediately following
|
|---|
| 166 | it. This block is treated as an anonymous sub, and so must have a
|
|---|
| 167 | semi-colon after the closing brace. Like C<Thread->new>, C<async>
|
|---|
| 168 | returns a thread object.
|
|---|
| 169 |
|
|---|
| 170 | =item Thread->self
|
|---|
| 171 |
|
|---|
| 172 | The C<Thread-E<gt>self> function returns a thread object that represents
|
|---|
| 173 | the thread making the C<Thread-E<gt>self> call.
|
|---|
| 174 |
|
|---|
| 175 | =item cond_wait VARIABLE
|
|---|
| 176 |
|
|---|
| 177 | The C<cond_wait> function takes a B<locked> variable as
|
|---|
| 178 | a parameter, unlocks the variable, and blocks until another thread
|
|---|
| 179 | does a C<cond_signal> or C<cond_broadcast> for that same locked
|
|---|
| 180 | variable. The variable that C<cond_wait> blocked on is relocked
|
|---|
| 181 | after the C<cond_wait> is satisfied. If there are multiple threads
|
|---|
| 182 | C<cond_wait>ing on the same variable, all but one will reblock waiting
|
|---|
| 183 | to reaquire the lock on the variable. (So if you're only using
|
|---|
| 184 | C<cond_wait> for synchronization, give up the lock as soon as
|
|---|
| 185 | possible.)
|
|---|
| 186 |
|
|---|
| 187 | =item cond_signal VARIABLE
|
|---|
| 188 |
|
|---|
| 189 | The C<cond_signal> function takes a locked variable as a parameter and
|
|---|
| 190 | unblocks one thread that's C<cond_wait>ing on that variable. If more than
|
|---|
| 191 | one thread is blocked in a C<cond_wait> on that variable, only one (and
|
|---|
| 192 | which one is indeterminate) will be unblocked.
|
|---|
| 193 |
|
|---|
| 194 | If there are no threads blocked in a C<cond_wait> on the variable,
|
|---|
| 195 | the signal is discarded.
|
|---|
| 196 |
|
|---|
| 197 | =item cond_broadcast VARIABLE
|
|---|
| 198 |
|
|---|
| 199 | The C<cond_broadcast> function works similarly to C<cond_signal>.
|
|---|
| 200 | C<cond_broadcast>, though, will unblock B<all> the threads that are
|
|---|
| 201 | blocked in a C<cond_wait> on the locked variable, rather than only
|
|---|
| 202 | one.
|
|---|
| 203 |
|
|---|
| 204 | =item yield
|
|---|
| 205 |
|
|---|
| 206 | The C<yield> function allows another thread to take control of the
|
|---|
| 207 | CPU. The exact results are implementation-dependent.
|
|---|
| 208 |
|
|---|
| 209 | =back
|
|---|
| 210 |
|
|---|
| 211 | =head1 METHODS
|
|---|
| 212 |
|
|---|
| 213 | =over 8
|
|---|
| 214 |
|
|---|
| 215 | =item join
|
|---|
| 216 |
|
|---|
| 217 | C<join> waits for a thread to end and returns any values the thread
|
|---|
| 218 | exited with. C<join> will block until the thread has ended, though
|
|---|
| 219 | it won't block if the thread has already terminated.
|
|---|
| 220 |
|
|---|
| 221 | If the thread being C<join>ed C<die>d, the error it died with will
|
|---|
| 222 | be returned at this time. If you don't want the thread performing
|
|---|
| 223 | the C<join> to die as well, you should either wrap the C<join> in
|
|---|
| 224 | an C<eval> or use the C<eval> thread method instead of C<join>.
|
|---|
| 225 |
|
|---|
| 226 | =item eval
|
|---|
| 227 |
|
|---|
| 228 | The C<eval> method wraps an C<eval> around a C<join>, and so waits for
|
|---|
| 229 | a thread to exit, passing along any values the thread might have returned.
|
|---|
| 230 | Errors, of course, get placed into C<$@>. (Not available with ithreads.)
|
|---|
| 231 |
|
|---|
| 232 | =item detach
|
|---|
| 233 |
|
|---|
| 234 | C<detach> tells a thread that it is never going to be joined i.e.
|
|---|
| 235 | that all traces of its existence can be removed once it stops running.
|
|---|
| 236 | Errors in detached threads will not be visible anywhere - if you want
|
|---|
| 237 | to catch them, you should use $SIG{__DIE__} or something like that.
|
|---|
| 238 |
|
|---|
| 239 | =item equal
|
|---|
| 240 |
|
|---|
| 241 | C<equal> tests whether two thread objects represent the same thread and
|
|---|
| 242 | returns true if they do.
|
|---|
| 243 |
|
|---|
| 244 | =item tid
|
|---|
| 245 |
|
|---|
| 246 | The C<tid> method returns the tid of a thread. The tid is
|
|---|
| 247 | a monotonically increasing integer assigned when a thread is
|
|---|
| 248 | created. The main thread of a program will have a tid of zero,
|
|---|
| 249 | while subsequent threads will have tids assigned starting with one.
|
|---|
| 250 |
|
|---|
| 251 | =item flags
|
|---|
| 252 |
|
|---|
| 253 | The C<flags> method returns the flags for the thread. This is the
|
|---|
| 254 | integer value corresponding to the internal flags for the thread,
|
|---|
| 255 | and the value may not be all that meaningful to you.
|
|---|
| 256 | (Not available with ithreads.)
|
|---|
| 257 |
|
|---|
| 258 | =item done
|
|---|
| 259 |
|
|---|
| 260 | The C<done> method returns true if the thread you're checking has
|
|---|
| 261 | finished, and false otherwise. (Not available with ithreads.)
|
|---|
| 262 |
|
|---|
| 263 | =back
|
|---|
| 264 |
|
|---|
| 265 | =head1 LIMITATIONS
|
|---|
| 266 |
|
|---|
| 267 | The sequence number used to assign tids is a simple integer, and no
|
|---|
| 268 | checking is done to make sure the tid isn't currently in use. If a
|
|---|
| 269 | program creates more than 2**32 - 1 threads in a single run, threads
|
|---|
| 270 | may be assigned duplicate tids. This limitation may be lifted in
|
|---|
| 271 | a future version of Perl.
|
|---|
| 272 |
|
|---|
| 273 | =head1 SEE ALSO
|
|---|
| 274 |
|
|---|
| 275 | L<threads::shared> (not available with 5005threads)
|
|---|
| 276 |
|
|---|
| 277 | L<attributes>, L<Thread::Queue>, L<Thread::Semaphore>,
|
|---|
| 278 | L<Thread::Specific> (not available with ithreads)
|
|---|
| 279 |
|
|---|
| 280 | =cut
|
|---|
| 281 |
|
|---|
| 282 | #
|
|---|
| 283 | # Methods
|
|---|
| 284 | #
|
|---|
| 285 |
|
|---|
| 286 | #
|
|---|
| 287 | # Exported functions
|
|---|
| 288 | #
|
|---|
| 289 |
|
|---|
| 290 | sub async (&) {
|
|---|
| 291 | return Thread->new($_[0]);
|
|---|
| 292 | }
|
|---|
| 293 |
|
|---|
| 294 | sub eval {
|
|---|
| 295 | return eval { shift->join; };
|
|---|
| 296 | }
|
|---|
| 297 |
|
|---|
| 298 | sub unimplemented {
|
|---|
| 299 | print $_[0], " unimplemented with ",
|
|---|
| 300 | $Config{useithreads} ? "ithreads" : "5005threads", "\n";
|
|---|
| 301 |
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | sub unimplement {
|
|---|
| 305 | for my $m (@_) {
|
|---|
| 306 | no strict 'refs';
|
|---|
| 307 | *{"Thread::$m"} = sub { unimplemented $m };
|
|---|
| 308 | }
|
|---|
| 309 | }
|
|---|
| 310 |
|
|---|
| 311 | BEGIN {
|
|---|
| 312 | if ($ithreads) {
|
|---|
| 313 | if ($othreads) {
|
|---|
| 314 | require Carp;
|
|---|
| 315 | Carp::croak("This Perl has both ithreads and 5005threads (serious malconfiguration)");
|
|---|
| 316 | }
|
|---|
| 317 | XSLoader::load 'threads';
|
|---|
| 318 | for my $m (qw(new join detach yield self tid equal list)) {
|
|---|
| 319 | no strict 'refs';
|
|---|
| 320 | *{"Thread::$m"} = \&{"threads::$m"};
|
|---|
| 321 | }
|
|---|
| 322 | require 'threads/shared.pm';
|
|---|
| 323 | for my $m (qw(cond_signal cond_broadcast cond_wait)) {
|
|---|
| 324 | no strict 'refs';
|
|---|
| 325 | *{"Thread::$m"} = \&{"threads::shared::${m}_enabled"};
|
|---|
| 326 | }
|
|---|
| 327 | # trying to unimplement eval gives redefined warning
|
|---|
| 328 | unimplement(qw(done flags));
|
|---|
| 329 | } elsif ($othreads) {
|
|---|
| 330 | XSLoader::load 'Thread';
|
|---|
| 331 | } else {
|
|---|
| 332 | require Carp;
|
|---|
| 333 | Carp::croak("This Perl has neither ithreads nor 5005threads");
|
|---|
| 334 | }
|
|---|
| 335 | }
|
|---|
| 336 |
|
|---|
| 337 | 1;
|
|---|