diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/debian-unstable/man3/threads.3perl | |
parent | Initial commit. (diff) | |
download | manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip |
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/debian-unstable/man3/threads.3perl')
-rw-r--r-- | upstream/debian-unstable/man3/threads.3perl | 1065 |
1 files changed, 1065 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man3/threads.3perl b/upstream/debian-unstable/man3/threads.3perl new file mode 100644 index 00000000..95de3d9d --- /dev/null +++ b/upstream/debian-unstable/man3/threads.3perl @@ -0,0 +1,1065 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "threads 3perl" +.TH threads 3perl 2024-01-12 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +threads \- Perl interpreter\-based threads +.SH VERSION +.IX Header "VERSION" +This document describes threads version 2.36 +.SH WARNING +.IX Header "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 makes them easy to misuse. Few people know how to +use them correctly or will be able to provide help. +.PP +The use of interpreter-based threads in perl is officially +discouraged. +.SH SYNOPSIS +.IX Header "SYNOPSIS" +.Vb 4 +\& use threads (\*(Aqyield\*(Aq, +\& \*(Aqstack_size\*(Aq => 64*4096, +\& \*(Aqexit\*(Aq => \*(Aqthreads_only\*(Aq, +\& \*(Aqstringify\*(Aq); +\& +\& sub start_thread { +\& my @args = @_; +\& print(\*(AqThread started: \*(Aq, join(\*(Aq \*(Aq, @args), "\en"); +\& } +\& my $thr = threads\->create(\*(Aqstart_thread\*(Aq, \*(Aqargument\*(Aq); +\& $thr\->join(); +\& +\& threads\->create(sub { print("I am a thread\en"); })\->join(); +\& +\& my $thr2 = async { foreach (@files) { ... } }; +\& $thr2\->join(); +\& if (my $err = $thr2\->error()) { +\& warn("Thread error: $err\en"); +\& } +\& +\& # 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({\*(Aqcontext\*(Aq => \*(Aqlist\*(Aq}, +\& sub { return (qw/a b c/); }); +\& my @results = $thr\->join(); +\& +\& $thr\->detach(); +\& +\& # Get a thread\*(Aqs object +\& $thr = threads\->self(); +\& $thr = threads\->object($tid); +\& +\& # Get a thread\*(Aqs ID +\& $tid = threads\->tid(); +\& $tid = $thr\->tid(); +\& $tid = "$thr"; +\& +\& # Give other threads a chance to run +\& threads\->yield(); +\& yield(); +\& +\& # Lists of non\-detached threads +\& my @threads = threads\->list(); +\& my $thread_count = threads\->list(); +\& +\& my @running = threads\->list(threads::running); +\& my @joinable = threads\->list(threads::joinable); +\& +\& # Test thread objects +\& if ($thr1 == $thr2) { +\& ... +\& } +\& +\& # Manage thread stack size +\& $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({ \*(Aqcontext\*(Aq => \*(Aqlist\*(Aq, +\& \*(Aqstack_size\*(Aq => 32*4096, +\& \*(Aqexit\*(Aq => \*(Aqthread_only\*(Aq }, +\& \e&foo); +\& +\& # Get thread\*(Aqs context +\& my $wantarray = $thr\->wantarray(); +\& +\& # Check thread\*(Aqs state +\& if ($thr\->is_running()) { +\& sleep(1); +\& } +\& if ($thr\->is_joinable()) { +\& $thr\->join(); +\& } +\& +\& # Send a signal to a thread +\& $thr\->kill(\*(AqSIGUSR1\*(Aq); +\& +\& # Exit a thread +\& threads\->exit(); +.Ve +.SH DESCRIPTION +.IX Header "DESCRIPTION" +Since Perl 5.8, thread programming has been available using a model called +\&\fIinterpreter threads\fR which provides a new Perl interpreter for each +thread, and, by default, results in no data or state information being shared +between threads. +.PP +(Prior to Perl 5.8, \fI5005threads\fR was available through the \f(CW\*(C`Thread.pm\*(C'\fR API. +This threading model has been deprecated, and was removed as of Perl 5.10.0.) +.PP +As just mentioned, all variables are, by default, thread local. To use shared +variables, you need to also load threads::shared: +.PP +.Vb 2 +\& use threads; +\& use threads::shared; +.Ve +.PP +When loading threads::shared, you must \f(CW\*(C`use threads\*(C'\fR before you +\&\f(CW\*(C`use threads::shared\*(C'\fR. (\f(CW\*(C`threads\*(C'\fR will emit a warning if you do it the +other way around.) +.PP +It is strongly recommended that you enable threads via \f(CW\*(C`use threads\*(C'\fR as early +as possible in your script. +.PP +If needed, scripts can be written so as to run on both threaded and +non-threaded Perls: +.PP +.Vb 8 +\& my $can_use_threads = eval \*(Aquse threads; 1\*(Aq; +\& if ($can_use_threads) { +\& # Do processing using threads +\& ... +\& } else { +\& # Do it without using threads +\& ... +\& } +.Ve +.ie n .IP "$thr = threads\->create(FUNCTION, ARGS)" 4 +.el .IP "\f(CW$thr\fR = threads\->create(FUNCTION, ARGS)" 4 +.IX Item "$thr = threads->create(FUNCTION, ARGS)" +This will create a new thread that will begin execution with the specified +entry point function, and give it the \fIARGS\fR list as parameters. It will +return the corresponding threads object, or \f(CW\*(C`undef\*(C'\fR if thread creation failed. +.Sp +\&\fIFUNCTION\fR may either be the name of a function, an anonymous subroutine, or +a code ref. +.Sp +.Vb 5 +\& my $thr = threads\->create(\*(Aqfunc_name\*(Aq, ...); +\& # or +\& my $thr = threads\->create(sub { ... }, ...); +\& # or +\& my $thr = threads\->create(\e&func, ...); +.Ve +.Sp +The \f(CW\*(C`\->new()\*(C'\fR method is an alias for \f(CW\*(C`\->create()\*(C'\fR. +.ie n .IP $thr\->\fBjoin()\fR 4 +.el .IP \f(CW$thr\fR\->\fBjoin()\fR 4 +.IX Item "$thr->join()" +This will wait for the corresponding thread to complete its execution. When +the thread finishes, \f(CW\*(C`\->join()\*(C'\fR will return the return value(s) of the +entry point function. +.Sp +The context (void, scalar or list) for the return value(s) for \f(CW\*(C`\->join()\*(C'\fR +is determined at the time of thread creation. +.Sp +.Vb 10 +\& # 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({\*(Aqcontext\*(Aq => \*(Aqlist\*(Aq}, +\& sub { +\& my @results = qw(a b c); +\& return (@results); +\& }); +\& # Retrieve list results from thread +\& my @res1 = $thr1\->join(); +\& +\& # 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(); +\& +\& # Create a thread in void context (explicit) +\& my $thr3 = threads\->create({\*(Aqvoid\*(Aq => 1}, +\& sub { print("Hello, world\en"); }); +\& # Join the thread in void context (i.e., no return value) +\& $thr3\->join(); +.Ve +.Sp +See "THREAD CONTEXT" for more details. +.Sp +If the program exits without all threads having either been joined or +detached, then a warning will be issued. +.Sp +Calling \f(CW\*(C`\->join()\*(C'\fR or \f(CW\*(C`\->detach()\*(C'\fR on an already joined thread will +cause an error to be thrown. +.ie n .IP $thr\->\fBdetach()\fR 4 +.el .IP \f(CW$thr\fR\->\fBdetach()\fR 4 +.IX Item "$thr->detach()" +Makes the thread unjoinable, and causes any eventual return value to be +discarded. When the program exits, any detached threads that are still +running are silently terminated. +.Sp +If the program exits without all threads having either been joined or +detached, then a warning will be issued. +.Sp +Calling \f(CW\*(C`\->join()\*(C'\fR or \f(CW\*(C`\->detach()\*(C'\fR on an already detached thread +will cause an error to be thrown. +.IP threads\->\fBdetach()\fR 4 +.IX Item "threads->detach()" +Class method that allows a thread to detach itself. +.IP threads\->\fBself()\fR 4 +.IX Item "threads->self()" +Class method that allows a thread to obtain its own \fIthreads\fR object. +.ie n .IP $thr\->\fBtid()\fR 4 +.el .IP \f(CW$thr\fR\->\fBtid()\fR 4 +.IX Item "$thr->tid()" +Returns the ID of the thread. Thread IDs are unique integers with the main +thread in a program being 0, and incrementing by 1 for every thread created. +.IP threads\->\fBtid()\fR 4 +.IX Item "threads->tid()" +Class method that allows a thread to obtain its own ID. +.IP """$thr""" 4 +.IX Item """$thr""" +If you add the \f(CW\*(C`stringify\*(C'\fR import option to your \f(CW\*(C`use threads\*(C'\fR declaration, +then using a threads object in a string or a string context (e.g., as a hash +key) will cause its ID to be used as the value: +.Sp +.Vb 1 +\& use threads qw(stringify); +\& +\& my $thr = threads\->create(...); +\& print("Thread $thr started\en"); # Prints: Thread 1 started +.Ve +.IP threads\->object($tid) 4 +.IX Item "threads->object($tid)" +This will return the \fIthreads\fR object for the \fIactive\fR thread associated +with the specified thread ID. If \f(CW$tid\fR is the value for the current thread, +then this call works the same as \f(CW\*(C`\->self()\*(C'\fR. Otherwise, returns \f(CW\*(C`undef\*(C'\fR +if there is no thread associated with the TID, if the thread is joined or +detached, if no TID is specified or if the specified TID is undef. +.IP threads\->\fByield()\fR 4 +.IX Item "threads->yield()" +This is a suggestion to the OS to let this thread yield CPU time to other +threads. What actually happens is highly dependent upon the underlying +thread implementation. +.Sp +You may do \f(CW\*(C`use threads qw(yield)\*(C'\fR, and then just use \f(CWyield()\fR in your +code. +.IP threads\->\fBlist()\fR 4 +.IX Item "threads->list()" +.PD 0 +.IP threads\->list(threads::all) 4 +.IX Item "threads->list(threads::all)" +.IP threads\->list(threads::running) 4 +.IX Item "threads->list(threads::running)" +.IP threads\->list(threads::joinable) 4 +.IX Item "threads->list(threads::joinable)" +.PD +With no arguments (or using \f(CW\*(C`threads::all\*(C'\fR) and in a list context, returns a +list of all non-joined, non-detached \fIthreads\fR objects. In a scalar context, +returns a count of the same. +.Sp +With a \fItrue\fR argument (using \f(CW\*(C`threads::running\*(C'\fR), returns a list of all +non-joined, non-detached \fIthreads\fR objects that are still running. +.Sp +With a \fIfalse\fR argument (using \f(CW\*(C`threads::joinable\*(C'\fR), returns a list of all +non-joined, non-detached \fIthreads\fR objects that have finished running (i.e., +for which \f(CW\*(C`\->join()\*(C'\fR will not \fIblock\fR). +.ie n .IP $thr1\->equal($thr2) 4 +.el .IP \f(CW$thr1\fR\->equal($thr2) 4 +.IX Item "$thr1->equal($thr2)" +Tests if two threads objects are the same thread or not. This is overloaded +to the more natural forms: +.Sp +.Vb 7 +\& if ($thr1 == $thr2) { +\& print("Threads are the same\en"); +\& } +\& # or +\& if ($thr1 != $thr2) { +\& print("Threads differ\en"); +\& } +.Ve +.Sp +(Thread comparison is based on thread IDs.) +.IP "async BLOCK;" 4 +.IX Item "async BLOCK;" +\&\f(CW\*(C`async\*(C'\fR creates a thread to execute the block immediately following +it. This block is treated as an anonymous subroutine, and so must have a +semicolon after the closing brace. Like \f(CW\*(C`threads\->create()\*(C'\fR, \f(CW\*(C`async\*(C'\fR +returns a \fIthreads\fR object. +.ie n .IP $thr\->\fBerror()\fR 4 +.el .IP \f(CW$thr\fR\->\fBerror()\fR 4 +.IX Item "$thr->error()" +Threads are executed in an \f(CW\*(C`eval\*(C'\fR context. This method will return \f(CW\*(C`undef\*(C'\fR +if the thread terminates \fInormally\fR. Otherwise, it returns the value of +\&\f(CW$@\fR associated with the thread's execution status in its \f(CW\*(C`eval\*(C'\fR context. +.ie n .IP $thr\->\fB_handle()\fR 4 +.el .IP \f(CW$thr\fR\->\fB_handle()\fR 4 +.IX Item "$thr->_handle()" +This \fIprivate\fR 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 \f(CW\*(C`HANDLE\*(C'\fR value returned +by \f(CW\*(C`CreateThread\*(C'\fR (i.e., \f(CW\*(C`HANDLE *\*(C'\fR); for other platforms, it is a pointer +to the \f(CW\*(C`pthread_t\*(C'\fR structure used in the \f(CW\*(C`pthread_create\*(C'\fR call (i.e., +\&\f(CW\*(C`pthread_t *\*(C'\fR). +.Sp +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 +possibly manipulate, the underlying thread structure associated with a Perl +thread. +.IP threads\->\fB_handle()\fR 4 +.IX Item "threads->_handle()" +Class method that allows a thread to obtain its own \fIhandle\fR. +.SH "EXITING A THREAD" +.IX Header "EXITING A THREAD" +The usual method for terminating a thread is to +\&\fBreturn()\fR from the entry point function with the +appropriate return value(s). +.IP threads\->\fBexit()\fR 4 +.IX Item "threads->exit()" +If needed, a thread can be exited at any time by calling +\&\f(CW\*(C`threads\->exit()\*(C'\fR. This will cause the thread to return \f(CW\*(C`undef\*(C'\fR in a +scalar context, or the empty list in a list context. +.Sp +When called from the \fImain\fR thread, this behaves the same as \f(CWexit(0)\fR. +.IP threads\->exit(status) 4 +.IX Item "threads->exit(status)" +When called from a thread, this behaves like \f(CW\*(C`threads\->exit()\*(C'\fR (i.e., the +exit status code is ignored). +.Sp +When called from the \fImain\fR thread, this behaves the same as \f(CWexit(status)\fR. +.IP \fBdie()\fR 4 +.IX Item "die()" +Calling \f(CWdie()\fR in a thread indicates an abnormal exit for the thread. Any +\&\f(CW$SIG{_\|_DIE_\|_}\fR 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 \f(CWdie()\fR call. +.IP exit(status) 4 +.IX Item "exit(status)" +Calling \fBexit()\fR inside a thread causes the whole +application to terminate. Because of this, the use of \f(CWexit()\fR inside +threaded code, or in modules that might be used in threaded applications, is +strongly discouraged. +.Sp +If \f(CWexit()\fR really is needed, then consider using the following: +.Sp +.Vb 2 +\& threads\->exit() if threads\->can(\*(Aqexit\*(Aq); # Thread friendly +\& exit(status); +.Ve +.IP "use threads 'exit' => 'threads_only'" 4 +.IX Item "use threads 'exit' => 'threads_only'" +This globally overrides the default behavior of calling \f(CWexit()\fR inside a +thread, and effectively causes such calls to behave the same as +\&\f(CW\*(C`threads\->exit()\*(C'\fR. In other words, with this setting, calling \f(CWexit()\fR +causes only the thread to terminate. +.Sp +Because of its global effect, this setting should not be used inside modules +or the like. +.Sp +The \fImain\fR thread is unaffected by this setting. +.IP "threads\->create({'exit' => 'thread_only'}, ...)" 4 +.IX Item "threads->create({'exit' => 'thread_only'}, ...)" +This overrides the default behavior of \f(CWexit()\fR inside the newly created +thread only. +.ie n .IP $thr\->set_thread_exit_only(boolean) 4 +.el .IP \f(CW$thr\fR\->set_thread_exit_only(boolean) 4 +.IX Item "$thr->set_thread_exit_only(boolean)" +This can be used to change the \fIexit thread only\fR behavior for a thread after +it has been created. With a \fItrue\fR argument, \f(CWexit()\fR will cause only the +thread to exit. With a \fIfalse\fR argument, \f(CWexit()\fR will terminate the +application. +.Sp +The \fImain\fR thread is unaffected by this call. +.IP threads\->set_thread_exit_only(boolean) 4 +.IX Item "threads->set_thread_exit_only(boolean)" +Class method for use inside a thread to change its own behavior for \f(CWexit()\fR. +.Sp +The \fImain\fR thread is unaffected by this call. +.SH "THREAD STATE" +.IX Header "THREAD STATE" +The following boolean methods are useful in determining the \fIstate\fR of a +thread. +.ie n .IP $thr\->\fBis_running()\fR 4 +.el .IP \f(CW$thr\fR\->\fBis_running()\fR 4 +.IX Item "$thr->is_running()" +Returns true if a thread is still running (i.e., if its entry point function +has not yet finished or exited). +.ie n .IP $thr\->\fBis_joinable()\fR 4 +.el .IP \f(CW$thr\fR\->\fBis_joinable()\fR 4 +.IX Item "$thr->is_joinable()" +Returns true if the thread has finished running, is not detached and has not +yet been joined. In other words, the thread is ready to be joined, and a call +to \f(CW\*(C`$thr\->join()\*(C'\fR will not \fIblock\fR. +.ie n .IP $thr\->\fBis_detached()\fR 4 +.el .IP \f(CW$thr\fR\->\fBis_detached()\fR 4 +.IX Item "$thr->is_detached()" +Returns true if the thread has been detached. +.IP threads\->\fBis_detached()\fR 4 +.IX Item "threads->is_detached()" +Class method that allows a thread to determine whether or not it is detached. +.SH "THREAD CONTEXT" +.IX Header "THREAD CONTEXT" +As with subroutines, the type of value returned from a thread's entry point +function may be determined by the thread's \fIcontext\fR: 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 +\&\fBwantarray()\fR. The thread may then specify a value of +the appropriate type to be returned from \f(CW\*(C`\->join()\*(C'\fR. +.SS "Explicit context" +.IX Subsection "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 \f(CW\*(C`\->create()\*(C'\fR with a hash reference +as the first argument: +.PP +.Vb 3 +\& my $thr = threads\->create({\*(Aqcontext\*(Aq => \*(Aqlist\*(Aq}, \e&foo); +\& ... +\& my @results = $thr\->join(); +.Ve +.PP +In the above, the threads object is returned to the parent thread in scalar +context, and the thread's entry point function \f(CW\*(C`foo\*(C'\fR will be called in list +(array) context such that the parent thread can receive a list (array) from +the \f(CW\*(C`\->join()\*(C'\fR call. (\f(CW\*(Aqarray\*(Aq\fR is synonymous with \f(CW\*(Aqlist\*(Aq\fR.) +.PP +Similarly, if you need the threads object, but your thread will not be +returning a value (i.e., \fIvoid\fR context), you would do the following: +.PP +.Vb 3 +\& my $thr = threads\->create({\*(Aqcontext\*(Aq => \*(Aqvoid\*(Aq}, \e&foo); +\& ... +\& $thr\->join(); +.Ve +.PP +The context type may also be used as the \fIkey\fR in the hash reference followed +by a \fItrue\fR value: +.PP +.Vb 4 +\& threads\->create({\*(Aqscalar\*(Aq => 1}, \e&foo); +\& ... +\& my ($thr) = threads\->list(); +\& my $result = $thr\->join(); +.Ve +.SS "Implicit context" +.IX Subsection "Implicit context" +If not explicitly stated, the thread's context is implied from the context +of the \f(CW\*(C`\->create()\*(C'\fR call: +.PP +.Vb 2 +\& # 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(...); +.Ve +.ie n .SS $thr\->\fBwantarray()\fP +.el .SS \f(CW$thr\fP\->\fBwantarray()\fP +.IX Subsection "$thr->wantarray()" +This returns the thread's context in the same manner as +\&\fBwantarray()\fR. +.SS threads\->\fBwantarray()\fP +.IX Subsection "threads->wantarray()" +Class method to return the current thread's context. This returns the same +value as running \fBwantarray()\fR inside the current +thread's entry point function. +.SH "THREAD STACK SIZE" +.IX Header "THREAD STACK SIZE" +The default per-thread stack size for different platforms varies +significantly, and is almost always far more than is needed for most +applications. On Win32, Perl's makefile explicitly sets the default stack to +16 MB; on most other platforms, the system default is used, which again may be +much larger than is needed. +.PP +By tuning the stack size to more accurately reflect your application's needs, +you may significantly reduce your application's memory usage, and increase the +number of simultaneously running threads. +.PP +Note that on Windows, address space allocation granularity is 64 KB, +therefore, setting the stack smaller than that on Win32 Perl will not save any +more memory. +.IP threads\->\fBget_stack_size()\fR; 4 +.IX Item "threads->get_stack_size();" +Returns the current default per-thread stack size. The default is zero, which +means the system default stack size is currently in use. +.ie n .IP "$size = $thr\->\fBget_stack_size()\fR;" 4 +.el .IP "\f(CW$size\fR = \f(CW$thr\fR\->\fBget_stack_size()\fR;" 4 +.IX Item "$size = $thr->get_stack_size();" +Returns the stack size for a particular thread. A return value of zero +indicates the system default stack size was used for the thread. +.ie n .IP "$old_size = threads\->set_stack_size($new_size);" 4 +.el .IP "\f(CW$old_size\fR = threads\->set_stack_size($new_size);" 4 +.IX Item "$old_size = threads->set_stack_size($new_size);" +Sets a new default per-thread stack size, and returns the previous setting. +.Sp +Some platforms have a minimum thread stack size. Trying to set the stack size +below this value will result in a warning, and the minimum stack size will be +used. +.Sp +Some Linux platforms have a maximum stack size. Setting too large of a stack +size will cause thread creation to fail. +.Sp +If needed, \f(CW$new_size\fR will be rounded up to the next multiple of the memory +page size (usually 4096 or 8192). +.Sp +Threads created after the stack size is set will then either call +\&\f(CWpthread_attr_setstacksize()\fR \fI(for pthreads platforms)\fR, or supply the +stack size to \f(CWCreateThread()\fR \fI(for Win32 Perl)\fR. +.Sp +(Obviously, this call does not affect any currently extant threads.) +.IP "use threads ('stack_size' => VALUE);" 4 +.IX Item "use threads ('stack_size' => VALUE);" +This sets the default per-thread stack size at the start of the application. +.ie n .IP $ENV{'PERL5_ITHREADS_STACK_SIZE'} 4 +.el .IP \f(CW$ENV\fR{'PERL5_ITHREADS_STACK_SIZE'} 4 +.IX Item "$ENV{'PERL5_ITHREADS_STACK_SIZE'}" +The default per-thread stack size may be set at the start of the application +through the use of the environment variable \f(CW\*(C`PERL5_ITHREADS_STACK_SIZE\*(C'\fR: +.Sp +.Vb 3 +\& PERL5_ITHREADS_STACK_SIZE=1048576 +\& export PERL5_ITHREADS_STACK_SIZE +\& perl \-e\*(Aquse threads; print(threads\->get_stack_size(), "\en")\*(Aq +.Ve +.Sp +This value overrides any \f(CW\*(C`stack_size\*(C'\fR parameter given to \f(CW\*(C`use threads\*(C'\fR. Its +primary purpose is to permit setting the per-thread stack size for legacy +threaded applications. +.IP "threads\->create({'stack_size' => VALUE}, FUNCTION, ARGS)" 4 +.IX Item "threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)" +To specify a particular stack size for any individual thread, call +\&\f(CW\*(C`\->create()\*(C'\fR with a hash reference as the first argument: +.Sp +.Vb 2 +\& my $thr = threads\->create({\*(Aqstack_size\*(Aq => 32*4096}, +\& \e&foo, @args); +.Ve +.ie n .IP "$thr2 = $thr1\->create(FUNCTION, ARGS)" 4 +.el .IP "\f(CW$thr2\fR = \f(CW$thr1\fR\->create(FUNCTION, ARGS)" 4 +.IX Item "$thr2 = $thr1->create(FUNCTION, ARGS)" +This creates a new thread (\f(CW$thr2\fR) that inherits the stack size from an +existing thread (\f(CW$thr1\fR). This is shorthand for the following: +.Sp +.Vb 3 +\& my $stack_size = $thr1\->get_stack_size(); +\& my $thr2 = threads\->create({\*(Aqstack_size\*(Aq => $stack_size}, +\& FUNCTION, ARGS); +.Ve +.SH "THREAD SIGNALLING" +.IX Header "THREAD SIGNALLING" +When safe signals is in effect (the default behavior \- see "Unsafe signals" +for more details), then signals may be sent and acted upon by individual +threads. +.ie n .IP $thr\->kill('SIG...'); 4 +.el .IP \f(CW$thr\fR\->kill('SIG...'); 4 +.IX Item "$thr->kill('SIG...');" +Sends the specified signal to the thread. Signal names and (positive) signal +numbers are the same as those supported by +\&\fBkill()\fR. For example, 'SIGTERM', 'TERM' and +(depending on the OS) 15 are all valid arguments to \f(CW\*(C`\->kill()\*(C'\fR. +.Sp +Returns the thread object to allow for method chaining: +.Sp +.Vb 1 +\& $thr\->kill(\*(AqSIG...\*(Aq)\->join(); +.Ve +.PP +Signal handlers need to be set up in the threads for the signals they are +expected to act upon. Here's an example for \fIcancelling\fR a thread: +.PP +.Vb 1 +\& use threads; +\& +\& sub thr_func +\& { +\& # Thread \*(Aqcancellation\*(Aq signal handler +\& $SIG{\*(AqKILL\*(Aq} = sub { threads\->exit(); }; +\& +\& ... +\& } +\& +\& # Create a thread +\& my $thr = threads\->create(\*(Aqthr_func\*(Aq); +\& +\& ... +\& +\& # Signal the thread to terminate, and then detach +\& # it so that it will get cleaned up automatically +\& $thr\->kill(\*(AqKILL\*(Aq)\->detach(); +.Ve +.PP +Here's another simplistic example that illustrates the use of thread +signalling in conjunction with a semaphore to provide rudimentary \fIsuspend\fR +and \fIresume\fR capabilities: +.PP +.Vb 2 +\& use threads; +\& use Thread::Semaphore; +\& +\& sub thr_func +\& { +\& my $sema = shift; +\& +\& # Thread \*(Aqsuspend/resume\*(Aq signal handler +\& $SIG{\*(AqSTOP\*(Aq} = sub { +\& $sema\->down(); # Thread suspended +\& $sema\->up(); # Thread resumes +\& }; +\& +\& ... +\& } +\& +\& # Create a semaphore and pass it to a thread +\& my $sema = Thread::Semaphore\->new(); +\& my $thr = threads\->create(\*(Aqthr_func\*(Aq, $sema); +\& +\& # Suspend the thread +\& $sema\->down(); +\& $thr\->kill(\*(AqSTOP\*(Aq); +\& +\& ... +\& +\& # Allow the thread to continue +\& $sema\->up(); +.Ve +.PP +CAVEAT: The thread signalling capability provided by this module does not +actually send signals via the OS. It \fIemulates\fR signals at the Perl-level +such that signal handlers are called in the appropriate thread. For example, +sending \f(CW\*(C`$thr\->kill(\*(AqSTOP\*(Aq)\*(C'\fR does not actually suspend a thread (or the +whole process), but does cause a \f(CW$SIG{\*(AqSTOP\*(Aq}\fR handler to be called in that +thread (as illustrated above). +.PP +As such, signals that would normally not be appropriate to use in the +\&\f(CWkill()\fR command (e.g., \f(CW\*(C`kill(\*(AqKILL\*(Aq, $$)\*(C'\fR) are okay to use with the +\&\f(CW\*(C`\->kill()\*(C'\fR method (again, as illustrated above). +.PP +Correspondingly, sending a signal to a thread does not disrupt the operation +the thread is currently working on: The signal will be acted upon after the +current operation has completed. For instance, if the thread is \fIstuck\fR on +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. +.PP +Sending a signal to a terminated/finished thread is ignored. +.SH WARNINGS +.IX Header "WARNINGS" +.IP "Perl exited with active threads:" 4 +.IX Item "Perl exited with active threads:" +If the program exits without all threads having either been joined or +detached, then this warning will be issued. +.Sp +NOTE: If the \fImain\fR thread exits, then this warning cannot be suppressed +using \f(CW\*(C`no warnings \*(Aqthreads\*(Aq;\*(C'\fR as suggested below. +.IP "Thread creation failed: pthread_create returned #" 4 +.IX Item "Thread creation failed: pthread_create returned #" +See the appropriate \fIman\fR page for \f(CW\*(C`pthread_create\*(C'\fR to determine the actual +cause for the failure. +.IP "Thread # terminated abnormally: ..." 4 +.IX Item "Thread # terminated abnormally: ..." +A thread terminated in some manner other than just returning from its entry +point function, or by using \f(CW\*(C`threads\->exit()\*(C'\fR. For example, the thread +may have terminated because of an error, or by using \f(CW\*(C`die\*(C'\fR. +.IP "Using minimum thread stack size of #" 4 +.IX Item "Using minimum thread stack size of #" +Some platforms have a minimum thread stack size. Trying to set the stack size +below this value will result in the above warning, and the stack size will be +set to the minimum. +.IP "Thread creation failed: pthread_attr_setstacksize(\fISIZE\fR) returned 22" 4 +.IX Item "Thread creation failed: pthread_attr_setstacksize(SIZE) returned 22" +The specified \fISIZE\fR exceeds the system's maximum stack size. Use a smaller +value for the stack size. +.PP +If needed, thread warnings can be suppressed by using: +.PP +.Vb 1 +\& no warnings \*(Aqthreads\*(Aq; +.Ve +.PP +in the appropriate scope. +.SH ERRORS +.IX Header "ERRORS" +.IP "This Perl not built to support threads" 4 +.IX Item "This Perl not built to support threads" +The particular copy of Perl that you're trying to use was not built using the +\&\f(CW\*(C`useithreads\*(C'\fR configuration option. +.Sp +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 +threads module (i.e., threaded and non-threaded Perls are binary +incompatible). +.IP "Cannot change stack size of an existing thread" 4 +.IX Item "Cannot change stack size of an existing thread" +The stack size of currently extant threads cannot be changed, therefore, the +following results in the above error: +.Sp +.Vb 1 +\& $thr\->set_stack_size($size); +.Ve +.IP "Cannot signal threads without safe signals" 4 +.IX Item "Cannot signal threads without safe signals" +Safe signals must be in effect to use the \f(CW\*(C`\->kill()\*(C'\fR signalling method. +See "Unsafe signals" for more details. +.IP "Unrecognized signal name: ..." 4 +.IX Item "Unrecognized signal name: ..." +The particular copy of Perl that you're trying to use does not support the +specified signal being used in a \f(CW\*(C`\->kill()\*(C'\fR call. +.SH "BUGS AND LIMITATIONS" +.IX Header "BUGS AND LIMITATIONS" +Before you consider posting a bug report, please consult, and possibly post a +message to the discussion forum to see if what you've encountered is a known +problem. +.IP "Thread-safe modules" 4 +.IX Item "Thread-safe modules" +See "Making your module threadsafe" in perlmod when creating modules that may +be used in threaded applications, especially if those modules use non-Perl +data, or XS code. +.IP "Using non-thread-safe modules" 4 +.IX Item "Using non-thread-safe modules" +Unfortunately, you may encounter Perl modules that are not \fIthread-safe\fR. +For example, they may crash the Perl interpreter during execution, or may dump +core on termination. Depending on the module and the requirements of your +application, it may be possible to work around such difficulties. +.Sp +If the module will only be used inside a thread, you can try loading the +module from inside the thread entry point function using \f(CW\*(C`require\*(C'\fR (and +\&\f(CW\*(C`import\*(C'\fR if needed): +.Sp +.Vb 4 +\& sub thr_func +\& { +\& require Unsafe::Module +\& # Unsafe::Module\->import(...); +\& +\& .... +\& } +.Ve +.Sp +If the module is needed inside the \fImain\fR thread, try modifying your +application so that the module is loaded (again using \f(CW\*(C`require\*(C'\fR and +\&\f(CW\*(C`\->import()\*(C'\fR) after any threads are started, and in such a way that no +other threads are started afterwards. +.Sp +If the above does not work, or is not adequate for your application, then file +a bug report on <https://rt.cpan.org/Public/> against the problematic module. +.IP "Memory consumption" 4 +.IX Item "Memory consumption" +On most systems, frequent and continual creation and destruction of threads +can lead to ever-increasing growth in the memory footprint of the Perl +interpreter. While it is simple to just launch threads and then +\&\f(CW\*(C`\->join()\*(C'\fR or \f(CW\*(C`\->detach()\*(C'\fR them, for long-lived applications, it is +better to maintain a pool of threads, and to reuse them for the work needed, +using queues to notify threads of pending work. The CPAN +distribution of this module contains a simple example +(\fIexamples/pool_reuse.pl\fR) illustrating the creation, use and monitoring of a +pool of \fIreusable\fR threads. +.IP "Current working directory" 4 +.IX Item "Current working directory" +On all platforms except MSWin32, the setting for the current working directory +is shared among all threads such that changing it in one thread (e.g., using +\&\f(CWchdir()\fR) will affect all the threads in the application. +.Sp +On MSWin32, each thread maintains its own the current working directory +setting. +.IP Locales 4 +.IX Item "Locales" +Prior to Perl 5.28, locales could not be used with threads, due to various +race conditions. Starting in that release, on systems that implement +thread-safe locale functions, threads can be used, with some caveats. +This includes Windows starting with Visual Studio 2005, and systems compatible +with POSIX 2008. See "Multi-threaded operation" in perllocale. +.Sp +Each thread (except the main thread) is started using the C locale. The main +thread is started like all other Perl programs; see "ENVIRONMENT" in perllocale. +You can switch locales in any thread as often as you like. +.Sp +If you want to inherit the parent thread's locale, you can, in the parent, set +a variable like so: +.Sp +.Vb 1 +\& $foo = POSIX::setlocale(LC_ALL, NULL); +.Ve +.Sp +and then pass to threads\->\fBcreate()\fR a sub that closes over \f(CW$foo\fR. Then, in +the child, you say +.Sp +.Vb 1 +\& POSIX::setlocale(LC_ALL, $foo); +.Ve +.Sp +Or you can use the facilities in threads::shared to pass \f(CW$foo\fR; +or if the environment hasn't changed, in the child, do +.Sp +.Vb 1 +\& POSIX::setlocale(LC_ALL, ""); +.Ve +.IP "Environment variables" 4 +.IX Item "Environment variables" +Currently, on all platforms except MSWin32, all \fIsystem\fR calls (e.g., using +\&\f(CWsystem()\fR or back-ticks) made from threads use the environment variable +settings from the \fImain\fR thread. In other words, changes made to \f(CW%ENV\fR in +a thread will not be visible in \fIsystem\fR calls made by that thread. +.Sp +To work around this, set environment variables as part of the \fIsystem\fR call. +For example: +.Sp +.Vb 2 +\& my $msg = \*(Aqhello\*(Aq; +\& system("FOO=$msg; echo \e$FOO"); # Outputs \*(Aqhello\*(Aq to STDOUT +.Ve +.Sp +On MSWin32, each thread maintains its own set of environment variables. +.IP "Catching signals" 4 +.IX Item "Catching signals" +Signals are \fIcaught\fR by the main thread (thread ID = 0) of a script. +Therefore, setting up signal handlers in threads for purposes other than +"THREAD SIGNALLING" as documented above will not accomplish what is +intended. +.Sp +This is especially true if trying to catch \f(CW\*(C`SIGALRM\*(C'\fR in a thread. To handle +alarms in threads, set up a signal handler in the main thread, and then use +"THREAD SIGNALLING" to relay the signal to the thread: +.Sp +.Vb 10 +\& # Create thread with a task that may time out +\& my $thr = threads\->create(sub { +\& threads\->yield(); +\& eval { +\& $SIG{ALRM} = sub { die("Timeout\en"); }; +\& alarm(10); +\& ... # Do work here +\& alarm(0); +\& }; +\& if ($@ =~ /Timeout/) { +\& warn("Task in thread timed out\en"); +\& } +\& }; +\& +\& # Set signal handler to relay SIGALRM to thread +\& $SIG{ALRM} = sub { $thr\->kill(\*(AqALRM\*(Aq) }; +\& +\& ... # Main thread continues working +.Ve +.IP "Parent-child threads" 4 +.IX Item "Parent-child threads" +On some platforms, it might not be possible to destroy \fIparent\fR threads while +there are still existing \fIchild\fR threads. +.IP "Unsafe signals" 4 +.IX Item "Unsafe signals" +Since Perl 5.8.0, signals have been made safer in Perl by postponing their +handling until the interpreter is in a \fIsafe\fR state. See +"Safe Signals" in perl58delta and "Deferred Signals (Safe Signals)" in perlipc +for more details. +.Sp +Safe signals is the default behavior, and the old, immediate, unsafe +signalling behavior is only in effect in the following situations: +.RS 4 +.IP \(bu 4 +Perl has been built with \f(CW\*(C`PERL_OLD_SIGNALS\*(C'\fR (see \f(CW\*(C`perl\ \-V\*(C'\fR). +.IP \(bu 4 +The environment variable \f(CW\*(C`PERL_SIGNALS\*(C'\fR is set to \f(CW\*(C`unsafe\*(C'\fR +(see "PERL_SIGNALS" in perlrun). +.IP \(bu 4 +The module Perl::Unsafe::Signals is used. +.RE +.RS 4 +.Sp +If unsafe signals is in effect, then signal handling is not thread-safe, and +the \f(CW\*(C`\->kill()\*(C'\fR signalling method cannot be used. +.RE +.IP "Identity of objects returned from threads" 4 +.IX Item "Identity of objects returned from threads" +When a value is returned from a thread through a \f(CW\*(C`join\*(C'\fR 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. +.Sp +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. +.IP "Returning blessed objects from threads" 4 +.IX Item "Returning blessed objects from threads" +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 Data::Dumper or Storable), and then +reconstituting it in the joining thread. If you're using Perl 5.10.0 or +later, and if the class supports shared objects, +you can pass them via shared queues. +.IP "END blocks in threads" 4 +.IX Item "END blocks in threads" +It is possible to add END blocks to threads by using require or +eval with the appropriate code. These \f(CW\*(C`END\*(C'\fR blocks +will then be executed when the thread's interpreter is destroyed (i.e., either +during a \f(CW\*(C`\->join()\*(C'\fR call, or at program termination). +.Sp +However, calling any threads methods in such an \f(CW\*(C`END\*(C'\fR block will most +likely \fIfail\fR (e.g., the application may hang, or generate an error) due to +mutexes that are needed to control functionality within the threads module. +.Sp +For this reason, the use of \f(CW\*(C`END\*(C'\fR blocks in threads is \fBstrongly\fR +discouraged. +.IP "Open directory handles" 4 +.IX Item "Open directory handles" +In perl 5.14 and higher, on systems other than Windows that do +not support the \f(CW\*(C`fchdir\*(C'\fR C function, directory handles (see +opendir) will not be copied to new +threads. You can use the \f(CW\*(C`d_fchdir\*(C'\fR variable in Config.pm to +determine whether your system supports it. +.Sp +In prior perl versions, spawning threads with open directory handles would +crash the interpreter. +[perl #75154] <https://rt.perl.org/rt3/Public/Bug/Display.html?id=75154> +.IP "Detached threads and global destruction" 4 +.IX 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. +.Sp +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. +.IP "Perl Bugs and the CPAN Version of threads" 4 +.IX Item "Perl Bugs and the CPAN Version of threads" +Support for threads extends beyond the code in this module (i.e., +\&\fIthreads.pm\fR and \fIthreads.xs\fR), and into the Perl interpreter itself. Older +versions of Perl contain bugs that may manifest themselves despite using the +latest version of threads from CPAN. There is no workaround for this other +than upgrading to the latest version of Perl. +.Sp +Even with the latest version of Perl, it is known that certain constructs +with threads may result in warning messages concerning leaked scalars or +unreferenced scalars. However, such warnings are harmless, and may safely be +ignored. +.Sp +You can search for threads related bug reports at +<https://rt.cpan.org/Public/>. If needed submit any new bugs, problems, +patches, etc. to: <https://rt.cpan.org/Public/Dist/Display.html?Name=threads> +.SH REQUIREMENTS +.IX Header "REQUIREMENTS" +Perl 5.8.0 or later +.SH "SEE ALSO" +.IX Header "SEE ALSO" +threads on MetaCPAN: +<https://metacpan.org/release/threads> +.PP +Code repository for CPAN distribution: +<https://github.com/Dual\-Life/threads> +.PP +threads::shared, perlthrtut +.PP +<https://www.perl.com/pub/a/2002/06/11/threads.html> and +<https://www.perl.com/pub/a/2002/09/04/threads.html> +.PP +Perl threads mailing list: +<https://lists.perl.org/list/ithreads.html> +.PP +Stack size discussion: +<https://www.perlmonks.org/?node_id=532956> +.PP +Sample code in the \fIexamples\fR directory of this distribution on CPAN. +.SH AUTHOR +.IX Header "AUTHOR" +Artur Bergman <sky AT crucially DOT net> +.PP +CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org> +.SH LICENSE +.IX Header "LICENSE" +threads is released under the same license as Perl. +.SH ACKNOWLEDGEMENTS +.IX Header "ACKNOWLEDGEMENTS" +Richard Soderberg <perl AT crystalflame DOT net> \- +Helping me out tons, trying to find reasons for races and other weird bugs! +.PP +Simon Cozens <simon AT brecon DOT co DOT uk> \- +Being there to answer zillions of annoying questions +.PP +Rocco Caputo <troc AT netrus DOT net> +.PP +Vipul Ved Prakash <mail AT vipul DOT net> \- +Helping with debugging +.PP +Dean Arnold <darnold AT presicient DOT com> \- +Stack size API |