X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/08d7a6b24064e70aacf57f27e3375e0256afc24a..019bf6638b0c7be4646504d16e256447855632d3:/pod/perlthrtut.pod diff --git a/pod/perlthrtut.pod b/pod/perlthrtut.pod index 55a4cd5..e885bb2 100644 --- a/pod/perlthrtut.pod +++ b/pod/perlthrtut.pod @@ -1,3 +1,5 @@ +=encoding utf8 + =head1 NAME perlthrtut - Tutorial on threads in Perl @@ -5,13 +7,13 @@ perlthrtut - Tutorial on threads in Perl =head1 DESCRIPTION This tutorial describes the use of Perl interpreter threads (sometimes -referred to as I) that was first introduced in Perl 5.6.0. In this +referred to as I). In this model, each thread runs in its own Perl interpreter, and any data sharing between threads must be explicit. The user-level interface for I uses the L class. B: There was another older Perl threading flavor called the 5.005 model -that used the L class. This old model was known to have problems, is +that used the L class. This old model was known to have problems, is deprecated, and was removed for release 5.10. You are strongly encouraged to migrate any existing 5.005 threads code to the new model as soon as possible. @@ -109,7 +111,7 @@ looking for implementation details you're going to be either disappointed or confused. Possibly both. This is not to say that Perl threads are completely different from -everything that's ever come before -- they're not. Perl's threading +everything that's ever come before. They're not. Perl's threading model owes a lot to other thread models, especially POSIX. Just as Perl is not C, though, Perl threads are not POSIX threads. So if you find yourself looking for mutexes, or thread priorities, it's time to @@ -161,7 +163,7 @@ make threaded programming easier. =head2 Basic Thread Support -Thread support is a Perl compile-time option -- it's something that's +Thread support is a Perl compile-time option. It's something that's turned on or off when Perl is built at your site, rather than when your programs are compiled. If your Perl wasn't compiled with thread support enabled, then any attempt to use threads will fail. @@ -171,7 +173,8 @@ enabled. If your program can't run without them, you can say something like: use Config; - $Config{useithreads} or die('Recompile Perl with threads to run this program.'); + $Config{useithreads} or + die('Recompile Perl with threads to run this program.'); A possibly-threaded program using a possibly-threaded module might have code like this: @@ -239,7 +242,7 @@ part of the Ccreate()> call, like this: sub sub1 { my @InboundParameters = @_; print("In the thread\n"); - print('Got parameters >', join('<>', @InboundParameters), "<\n"); + print('Got parameters >', join('<>',@InboundParameters), "<\n"); } The last example illustrates another feature of threads. You can spawn @@ -275,7 +278,7 @@ instead, as described next. NOTE: In the example above, the thread returns a list, thus necessitating that the thread creation call be made in list context (i.e., C). -See Ljoin()"> and L for more +See L<< threads/"$thr->join()" >> and L for more details on thread context and return values. =head2 Ignoring A Thread @@ -366,7 +369,7 @@ threading, or for that matter, to most other threading systems out there, is that by default, no data is shared. When a new Perl thread is created, all the data associated with the current thread is copied to the new thread, and is subsequently private to that new thread! -This is similar in feel to what happens when a UNIX process forks, +This is similar in feel to what happens when a Unix process forks, except that in this case, the data is just copied to a different part of memory within the same process rather than a real fork taking place. @@ -400,7 +403,8 @@ assignment will cause the thread to die. For example: ... create some threads ... - $hash{a} = 1; # All threads see exists($hash{a}) and $hash{a} == 1 + $hash{a} = 1; # All threads see exists($hash{a}) + # and $hash{a} == 1 $hash{a} = $var; # okay - copy-by-value: same effect as previous $hash{a} = $svar; # okay - copy-by-value: same effect as previous $hash{a} = \$svar; # okay - a reference to a shared variable @@ -672,7 +676,8 @@ gives a quick demonstration: while ($TryCount--) { $semaphore->down(); $LocalCopy = $GlobalVariable; - print("$TryCount tries left for sub $SubNumber (\$GlobalVariable is $GlobalVariable)\n"); + print("$TryCount tries left for sub $SubNumber " + ."(\$GlobalVariable is $GlobalVariable)\n"); sleep(2); $LocalCopy++; $GlobalVariable = $LocalCopy; @@ -739,7 +744,7 @@ Semaphores with counters greater than one are also useful for establishing quotas. Say, for example, that you have a number of threads that can do I/O at once. You don't want all the threads reading or writing at once though, since that can potentially swamp -your I/O channels, or deplete your process' quota of filehandles. You +your I/O channels, or deplete your process's quota of filehandles. You can use a semaphore initialized to the number of concurrent I/O requests (or open files) that you want at any one time, and have your threads quietly block and unblock themselves. @@ -844,40 +849,40 @@ does not appear in the list returned by Clist()>. Confused yet? It's time for an example program to show some of the things we've covered. This program finds prime numbers using threads. - 1 #!/usr/bin/perl - 2 # prime-pthread, courtesy of Tom Christiansen - 3 - 4 use strict; - 5 use warnings; - 6 - 7 use threads; - 8 use Thread::Queue; - 9 - 10 sub check_num { - 11 my ($upstream, $cur_prime) = @_; - 12 my $kid; - 13 my $downstream = Thread::Queue->new(); - 14 while (my $num = $upstream->dequeue()) { - 15 next unless ($num % $cur_prime); - 16 if ($kid) { - 17 $downstream->enqueue($num); - 18 } else { - 19 print("Found prime: $num\n"); - 20 $kid = threads->create(\&check_num, $downstream, $num); - 21 if (! $kid) { - 22 warn("Sorry. Ran out of threads.\n"); - 23 last; - 24 } - 25 } - 26 } - 27 if ($kid) { - 28 $downstream->enqueue(undef); - 29 $kid->join(); - 30 } - 31 } - 32 - 33 my $stream = Thread::Queue->new(3..1000, undef); - 34 check_num($stream, 2); + 1 #!/usr/bin/perl + 2 # prime-pthread, courtesy of Tom Christiansen + 3 + 4 use strict; + 5 use warnings; + 6 + 7 use threads; + 8 use Thread::Queue; + 9 + 10 sub check_num { + 11 my ($upstream, $cur_prime) = @_; + 12 my $kid; + 13 my $downstream = Thread::Queue->new(); + 14 while (my $num = $upstream->dequeue()) { + 15 next unless ($num % $cur_prime); + 16 if ($kid) { + 17 $downstream->enqueue($num); + 18 } else { + 19 print("Found prime: $num\n"); + 20 $kid = threads->create(\&check_num, $downstream, $num); + 21 if (! $kid) { + 22 warn("Sorry. Ran out of threads.\n"); + 23 last; + 24 } + 25 } + 26 } + 27 if ($kid) { + 28 $downstream->enqueue(undef); + 29 $kid->join(); + 30 } + 31 } + 32 + 33 my $stream = Thread::Queue->new(3..1000, undef); + 34 check_num($stream, 2); This program uses the pipeline model to generate prime numbers. Each thread in the pipeline has an input queue that feeds numbers to be @@ -1003,7 +1008,7 @@ all the variables and data of the parent thread has to be taken. Thus, thread creation can be quite expensive, both in terms of memory usage and time spent in creation. The ideal way to reduce these costs is to have a relatively short number of long-lived threads, all created fairly early -on -- before the base thread has accumulated too much data. Of course, this +on (before the base thread has accumulated too much data). Of course, this may not always be possible, so compromises have to be made. However, after a thread has been created, its performance and extra memory usage should be little different than ordinary code. @@ -1030,7 +1035,7 @@ changing uids and gids. Thinking of mixing C and threads? Please lie down and wait until the feeling passes. Be aware that the semantics of C vary -between platforms. For example, some UNIX systems copy all the current +between platforms. For example, some Unix systems copy all the current threads into the child process, while others only copy the thread that called C. You have been warned! @@ -1041,7 +1046,7 @@ give you the full POSIX API). For example, there is no way to guarantee that a signal sent to a multi-threaded Perl application will get intercepted by any particular thread. (However, a recently added feature does provide the capability to send signals between -threads. See L for more details.) +threads. See L for more details.) =head1 Thread-Safety of System Libraries @@ -1049,9 +1054,8 @@ Whether various library calls are thread-safe is outside the control of Perl. Calls often suffering from not being thread-safe include: C, C, functions fetching user, group and network information (such as C, C, -C and so on), C, -C, and C -- in general, calls that depend on some global -external state. +C and so on), C, C, and C. In +general, calls that depend on some global external state. If the system Perl is compiled in has thread-safe variants of such calls, they will be used. Beyond that, Perl is at the mercy of @@ -1079,21 +1083,21 @@ on your way to becoming a threaded Perl expert. Annotated POD for L: L -Lastest version of L on CPAN: +Latest version of L on CPAN: L Annotated POD for L: L -Lastest version of L on CPAN: +Latest version of L on CPAN: L Perl threads mailing list: -L +L =head1 Bibliography -Here's a short bibliography courtesy of Jürgen Christoffel: +Here's a short bibliography courtesy of Jürgen Christoffel: =head2 Introductory Texts @@ -1150,7 +1154,7 @@ L =head1 Acknowledgements Thanks (in no particular order) to Chaim Frenkel, Steve Fink, Gurusamy -Sarathy, Ilya Zakharevich, Benjamin Sugars, Jürgen Christoffel, Joshua +Sarathy, Ilya Zakharevich, Benjamin Sugars, Jürgen Christoffel, Joshua Pritikin, and Alan Burlison, for their help in reality-checking and polishing this article. Big thanks to Tom Christiansen for his rewrite of the prime number generator. @@ -1161,7 +1165,7 @@ Dan Sugalski Edan@sidhe.org Slightly modified by Arthur Bergman to fit the new thread model/module. -Reworked slightly by Jörg Walter Ejwalt@cpan.org to be more concise +Reworked slightly by Jörg Walter Ejwalt@cpan.org to be more concise about thread-safety of Perl code. Rearranged slightly by Elizabeth Mattijsen Eliz@dijkmat.nl to put