1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627 |
- @node POSIX Threads
- @c @node POSIX Threads, , Top, Top
- @chapter POSIX Threads
- @c %MENU% The standard threads library
- @c This chapter needs more work bigtime. -zw
- This chapter describes the pthreads (POSIX threads) library. This
- library provides support functions for multithreaded programs: thread
- primitives, synchronization objects, and so forth. It also implements
- POSIX 1003.1b semaphores (not to be confused with System V semaphores).
- The threads operations (@samp{pthread_*}) do not use @var{errno}.
- Instead they return an error code directly. The semaphore operations do
- use @var{errno}.
- @menu
- * Basic Thread Operations:: Creating, terminating, and waiting for threads.
- * Thread Attributes:: Tuning thread scheduling.
- * Cancellation:: Stopping a thread before it's done.
- * Cleanup Handlers:: Deallocating resources when a thread is
- canceled.
- * Mutexes:: One way to synchronize threads.
- * Condition Variables:: Another way.
- * POSIX Semaphores:: And a third way.
- * Thread-Specific Data:: Variables with different values in
- different threads.
- * Threads and Signal Handling:: Why you should avoid mixing the two, and
- how to do it if you must.
- * Threads and Fork:: Interactions between threads and the
- @code{fork} function.
- * Streams and Fork:: Interactions between stdio streams and
- @code{fork}.
- * Miscellaneous Thread Functions:: A grab bag of utility routines.
- @end menu
- @node Basic Thread Operations
- @section Basic Thread Operations
- These functions are the thread equivalents of @code{fork}, @code{exit},
- and @code{wait}.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_create (pthread_t * @var{thread}, pthread_attr_t * @var{attr}, void * (*@var{start_routine})(void *), void * @var{arg})
- @code{pthread_create} creates a new thread of control that executes
- concurrently with the calling thread. The new thread calls the
- function @var{start_routine}, passing it @var{arg} as first argument. The
- new thread terminates either explicitly, by calling @code{pthread_exit},
- or implicitly, by returning from the @var{start_routine} function. The
- latter case is equivalent to calling @code{pthread_exit} with the result
- returned by @var{start_routine} as exit code.
- The @var{attr} argument specifies thread attributes to be applied to the
- new thread. @xref{Thread Attributes}, for details. The @var{attr}
- argument can also be @code{NULL}, in which case default attributes are
- used: the created thread is joinable (not detached) and has an ordinary
- (not realtime) scheduling policy.
- On success, the identifier of the newly created thread is stored in the
- location pointed by the @var{thread} argument, and a 0 is returned. On
- error, a non-zero error code is returned.
- This function may return the following errors:
- @table @code
- @item EAGAIN
- Not enough system resources to create a process for the new thread,
- or more than @code{PTHREAD_THREADS_MAX} threads are already active.
- @end table
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun void pthread_exit (void *@var{retval})
- @code{pthread_exit} terminates the execution of the calling thread. All
- cleanup handlers (@pxref{Cleanup Handlers}) that have been set for the
- calling thread with @code{pthread_cleanup_push} are executed in reverse
- order (the most recently pushed handler is executed first). Finalization
- functions for thread-specific data are then called for all keys that
- have non-@code{NULL} values associated with them in the calling thread
- (@pxref{Thread-Specific Data}). Finally, execution of the calling
- thread is stopped.
- The @var{retval} argument is the return value of the thread. It can be
- retrieved from another thread using @code{pthread_join}.
- The @code{pthread_exit} function never returns.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cancel (pthread_t @var{thread})
- @code{pthread_cancel} sends a cancellation request to the thread denoted
- by the @var{thread} argument. If there is no such thread,
- @code{pthread_cancel} fails and returns @code{ESRCH}. Otherwise it
- returns 0. @xref{Cancellation}, for details.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_join (pthread_t @var{th}, void **thread_@var{return})
- @code{pthread_join} suspends the execution of the calling thread until
- the thread identified by @var{th} terminates, either by calling
- @code{pthread_exit} or by being canceled.
- If @var{thread_return} is not @code{NULL}, the return value of @var{th}
- is stored in the location pointed to by @var{thread_return}. The return
- value of @var{th} is either the argument it gave to @code{pthread_exit},
- or @code{PTHREAD_CANCELED} if @var{th} was canceled.
- The joined thread @code{th} must be in the joinable state: it must not
- have been detached using @code{pthread_detach} or the
- @code{PTHREAD_CREATE_DETACHED} attribute to @code{pthread_create}.
- When a joinable thread terminates, its memory resources (thread
- descriptor and stack) are not deallocated until another thread performs
- @code{pthread_join} on it. Therefore, @code{pthread_join} must be called
- once for each joinable thread created to avoid memory leaks.
- At most one thread can wait for the termination of a given
- thread. Calling @code{pthread_join} on a thread @var{th} on which
- another thread is already waiting for termination returns an error.
- @code{pthread_join} is a cancellation point. If a thread is canceled
- while suspended in @code{pthread_join}, the thread execution resumes
- immediately and the cancellation is executed without waiting for the
- @var{th} thread to terminate. If cancellation occurs during
- @code{pthread_join}, the @var{th} thread remains not joined.
- On success, the return value of @var{th} is stored in the location
- pointed to by @var{thread_return}, and 0 is returned. On error, one of
- the following values is returned:
- @table @code
- @item ESRCH
- No thread could be found corresponding to that specified by @var{th}.
- @item EINVAL
- The @var{th} thread has been detached, or another thread is already
- waiting on termination of @var{th}.
- @item EDEADLK
- The @var{th} argument refers to the calling thread.
- @end table
- @end deftypefun
- @node Thread Attributes
- @section Thread Attributes
- @comment pthread.h
- @comment POSIX
- Threads have a number of attributes that may be set at creation time.
- This is done by filling a thread attribute object @var{attr} of type
- @code{pthread_attr_t}, then passing it as second argument to
- @code{pthread_create}. Passing @code{NULL} is equivalent to passing a
- thread attribute object with all attributes set to their default values.
- Attribute objects are consulted only when creating a new thread. The
- same attribute object can be used for creating several threads.
- Modifying an attribute object after a call to @code{pthread_create} does
- not change the attributes of the thread previously created.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_attr_init (pthread_attr_t *@var{attr})
- @code{pthread_attr_init} initializes the thread attribute object
- @var{attr} and fills it with default values for the attributes. (The
- default values are listed below for each attribute.)
- Each attribute @var{attrname} (see below for a list of all attributes)
- can be individually set using the function
- @code{pthread_attr_set@var{attrname}} and retrieved using the function
- @code{pthread_attr_get@var{attrname}}.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_attr_destroy (pthread_attr_t *@var{attr})
- @code{pthread_attr_destroy} destroys the attribute object pointed to by
- @var{attr} releasing any resources associated with it. @var{attr} is
- left in an undefined state, and you must not use it again in a call to
- any pthreads function until it has been reinitialized.
- @end deftypefun
- @findex pthread_attr_setdetachstate
- @findex pthread_attr_setguardsize
- @findex pthread_attr_setinheritsched
- @findex pthread_attr_setschedparam
- @findex pthread_attr_setschedpolicy
- @findex pthread_attr_setscope
- @findex pthread_attr_setstack
- @findex pthread_attr_setstackaddr
- @findex pthread_attr_setstacksize
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_attr_setattr (pthread_attr_t *@var{obj}, int @var{value})
- Set attribute @var{attr} to @var{value} in the attribute object pointed
- to by @var{obj}. See below for a list of possible attributes and the
- values they can take.
- On success, these functions return 0. If @var{value} is not meaningful
- for the @var{attr} being modified, they will return the error code
- @code{EINVAL}. Some of the functions have other failure modes; see
- below.
- @end deftypefun
- @findex pthread_attr_getdetachstate
- @findex pthread_attr_getguardsize
- @findex pthread_attr_getinheritsched
- @findex pthread_attr_getschedparam
- @findex pthread_attr_getschedpolicy
- @findex pthread_attr_getscope
- @findex pthread_attr_getstack
- @findex pthread_attr_getstackaddr
- @findex pthread_attr_getstacksize
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_attr_getattr (const pthread_attr_t *@var{obj}, int *@var{value})
- Store the current setting of @var{attr} in @var{obj} into the variable
- pointed to by @var{value}.
- These functions always return 0.
- @end deftypefun
- The following thread attributes are supported:
- @table @samp
- @item detachstate
- Choose whether the thread is created in the joinable state (value
- @code{PTHREAD_CREATE_JOINABLE}) or in the detached state
- (@code{PTHREAD_CREATE_DETACHED}). The default is
- @code{PTHREAD_CREATE_JOINABLE}.
- In the joinable state, another thread can synchronize on the thread
- termination and recover its termination code using @code{pthread_join},
- but some of the thread resources are kept allocated after the thread
- terminates, and reclaimed only when another thread performs
- @code{pthread_join} on that thread.
- In the detached state, the thread resources are immediately freed when
- it terminates, but @code{pthread_join} cannot be used to synchronize on
- the thread termination.
- A thread created in the joinable state can later be put in the detached
- thread using @code{pthread_detach}.
- @item schedpolicy
- Select the scheduling policy for the thread: one of @code{SCHED_OTHER}
- (regular, non-realtime scheduling), @code{SCHED_RR} (realtime,
- round-robin) or @code{SCHED_FIFO} (realtime, first-in first-out).
- The default is @code{SCHED_OTHER}.
- @c Not doc'd in our manual: FIXME.
- @c See @code{sched_setpolicy} for more information on scheduling policies.
- The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO}
- are available only to processes with superuser privileges.
- @code{pthread_attr_setschedparam} will fail and return @code{ENOTSUP} if
- you try to set a realtime policy when you are unprivileged.
- The scheduling policy of a thread can be changed after creation with
- @code{pthread_setschedparam}.
- @item schedparam
- Change the scheduling parameter (the scheduling priority)
- for the thread. The default is 0.
- This attribute is not significant if the scheduling policy is
- @code{SCHED_OTHER}; it only matters for the realtime policies
- @code{SCHED_RR} and @code{SCHED_FIFO}.
- The scheduling priority of a thread can be changed after creation with
- @code{pthread_setschedparam}.
- @item inheritsched
- Choose whether the scheduling policy and scheduling parameter for the
- newly created thread are determined by the values of the
- @var{schedpolicy} and @var{schedparam} attributes (value
- @code{PTHREAD_EXPLICIT_SCHED}) or are inherited from the parent thread
- (value @code{PTHREAD_INHERIT_SCHED}). The default is
- @code{PTHREAD_EXPLICIT_SCHED}.
- @item scope
- Choose the scheduling contention scope for the created thread. The
- default is @code{PTHREAD_SCOPE_SYSTEM}, meaning that the threads contend
- for CPU time with all processes running on the machine. In particular,
- thread priorities are interpreted relative to the priorities of all
- other processes on the machine. The other possibility,
- @code{PTHREAD_SCOPE_PROCESS}, means that scheduling contention occurs
- only between the threads of the running process: thread priorities are
- interpreted relative to the priorities of the other threads of the
- process, regardless of the priorities of other processes.
- @code{PTHREAD_SCOPE_PROCESS} is not supported in LinuxThreads. If you
- try to set the scope to this value, @code{pthread_attr_setscope} will
- fail and return @code{ENOTSUP}.
- @item stackaddr
- Provide an address for an application managed stack. The size of the
- stack must be at least @code{PTHREAD_STACK_MIN}.
- @item stacksize
- Change the size of the stack created for the thread. The value defines
- the minimum stack size, in bytes.
- If the value exceeds the system's maximum stack size, or is smaller
- than @code{PTHREAD_STACK_MIN}, @code{pthread_attr_setstacksize} will
- fail and return @code{EINVAL}.
- @item stack
- Provide both the address and size of an application managed stack to
- use for the new thread. The base of the memory area is @var{stackaddr}
- with the size of the memory area, @var{stacksize}, measured in bytes.
- If the value of @var{stacksize} is less than @code{PTHREAD_STACK_MIN},
- or greater than the system's maximum stack size, or if the value of
- @var{stackaddr} lacks the proper alignment, @code{pthread_attr_setstack}
- will fail and return @code{EINVAL}.
- @item guardsize
- Change the minimum size in bytes of the guard area for the thread's
- stack. The default size is a single page. If this value is set, it
- will be rounded up to the nearest page size. If the value is set to 0,
- a guard area will not be created for this thread. The space allocated
- for the guard area is used to catch stack overflow. Therefore, when
- allocating large structures on the stack, a larger guard area may be
- required to catch a stack overflow.
- If the caller is managing their own stacks (if the @code{stackaddr}
- attribute has been set), then the @code{guardsize} attribute is ignored.
- If the value exceeds the @code{stacksize}, @code{pthread_atrr_setguardsize}
- will fail and return @code{EINVAL}.
- @end table
- @node Cancellation
- @section Cancellation
- Cancellation is the mechanism by which a thread can terminate the
- execution of another thread. More precisely, a thread can send a
- cancellation request to another thread. Depending on its settings, the
- target thread can then either ignore the request, honor it immediately,
- or defer it till it reaches a cancellation point. When threads are
- first created by @code{pthread_create}, they always defer cancellation
- requests.
- When a thread eventually honors a cancellation request, it behaves as if
- @code{pthread_exit(PTHREAD_CANCELED)} was called. All cleanup handlers
- are executed in reverse order, finalization functions for
- thread-specific data are called, and finally the thread stops executing.
- If the canceled thread was joinable, the return value
- @code{PTHREAD_CANCELED} is provided to whichever thread calls
- @var{pthread_join} on it. See @code{pthread_exit} for more information.
- Cancellation points are the points where the thread checks for pending
- cancellation requests and performs them. The POSIX threads functions
- @code{pthread_join}, @code{pthread_cond_wait},
- @code{pthread_cond_timedwait}, @code{pthread_testcancel},
- @code{sem_wait}, and @code{sigwait} are cancellation points. In
- addition, these system calls are cancellation points:
- @multitable @columnfractions .33 .33 .33
- @item @t{accept} @tab @t{open} @tab @t{sendmsg}
- @item @t{close} @tab @t{pause} @tab @t{sendto}
- @item @t{connect} @tab @t{read} @tab @t{system}
- @item @t{fcntl} @tab @t{recv} @tab @t{tcdrain}
- @item @t{fsync} @tab @t{recvfrom} @tab @t{wait}
- @item @t{lseek} @tab @t{recvmsg} @tab @t{waitpid}
- @item @t{msync} @tab @t{send} @tab @t{write}
- @item @t{nanosleep}
- @end multitable
- @noindent
- All library functions that call these functions (such as
- @code{printf}) are also cancellation points.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_setcancelstate (int @var{state}, int *@var{oldstate})
- @code{pthread_setcancelstate} changes the cancellation state for the
- calling thread -- that is, whether cancellation requests are ignored or
- not. The @var{state} argument is the new cancellation state: either
- @code{PTHREAD_CANCEL_ENABLE} to enable cancellation, or
- @code{PTHREAD_CANCEL_DISABLE} to disable cancellation (cancellation
- requests are ignored).
- If @var{oldstate} is not @code{NULL}, the previous cancellation state is
- stored in the location pointed to by @var{oldstate}, and can thus be
- restored later by another call to @code{pthread_setcancelstate}.
- If the @var{state} argument is not @code{PTHREAD_CANCEL_ENABLE} or
- @code{PTHREAD_CANCEL_DISABLE}, @code{pthread_setcancelstate} fails and
- returns @code{EINVAL}. Otherwise it returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_setcanceltype (int @var{type}, int *@var{oldtype})
- @code{pthread_setcanceltype} changes the type of responses to
- cancellation requests for the calling thread: asynchronous (immediate)
- or deferred. The @var{type} argument is the new cancellation type:
- either @code{PTHREAD_CANCEL_ASYNCHRONOUS} to cancel the calling thread
- as soon as the cancellation request is received, or
- @code{PTHREAD_CANCEL_DEFERRED} to keep the cancellation request pending
- until the next cancellation point. If @var{oldtype} is not @code{NULL},
- the previous cancellation state is stored in the location pointed to by
- @var{oldtype}, and can thus be restored later by another call to
- @code{pthread_setcanceltype}.
- If the @var{type} argument is not @code{PTHREAD_CANCEL_DEFERRED} or
- @code{PTHREAD_CANCEL_ASYNCHRONOUS}, @code{pthread_setcanceltype} fails
- and returns @code{EINVAL}. Otherwise it returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun void pthread_testcancel (@var{void})
- @code{pthread_testcancel} does nothing except testing for pending
- cancellation and executing it. Its purpose is to introduce explicit
- checks for cancellation in long sequences of code that do not call
- cancellation point functions otherwise.
- @end deftypefun
- @node Cleanup Handlers
- @section Cleanup Handlers
- Cleanup handlers are functions that get called when a thread terminates,
- either by calling @code{pthread_exit} or because of
- cancellation. Cleanup handlers are installed and removed following a
- stack-like discipline.
- The purpose of cleanup handlers is to free the resources that a thread
- may hold at the time it terminates. In particular, if a thread exits or
- is canceled while it owns a locked mutex, the mutex will remain locked
- forever and prevent other threads from executing normally. The best way
- to avoid this is, just before locking the mutex, to install a cleanup
- handler whose effect is to unlock the mutex. Cleanup handlers can be
- used similarly to free blocks allocated with @code{malloc} or close file
- descriptors on thread termination.
- Here is how to lock a mutex @var{mut} in such a way that it will be
- unlocked if the thread is canceled while @var{mut} is locked:
- @smallexample
- pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
- pthread_mutex_lock(&mut);
- /* do some work */
- pthread_mutex_unlock(&mut);
- pthread_cleanup_pop(0);
- @end smallexample
- Equivalently, the last two lines can be replaced by
- @smallexample
- pthread_cleanup_pop(1);
- @end smallexample
- Notice that the code above is safe only in deferred cancellation mode
- (see @code{pthread_setcanceltype}). In asynchronous cancellation mode, a
- cancellation can occur between @code{pthread_cleanup_push} and
- @code{pthread_mutex_lock}, or between @code{pthread_mutex_unlock} and
- @code{pthread_cleanup_pop}, resulting in both cases in the thread trying
- to unlock a mutex not locked by the current thread. This is the main
- reason why asynchronous cancellation is difficult to use.
- If the code above must also work in asynchronous cancellation mode,
- then it must switch to deferred mode for locking and unlocking the
- mutex:
- @smallexample
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
- pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
- pthread_mutex_lock(&mut);
- /* do some work */
- pthread_cleanup_pop(1);
- pthread_setcanceltype(oldtype, NULL);
- @end smallexample
- The code above can be rewritten in a more compact and efficient way,
- using the non-portable functions @code{pthread_cleanup_push_defer_np}
- and @code{pthread_cleanup_pop_restore_np}:
- @smallexample
- pthread_cleanup_push_defer_np(pthread_mutex_unlock, (void *) &mut);
- pthread_mutex_lock(&mut);
- /* do some work */
- pthread_cleanup_pop_restore_np(1);
- @end smallexample
- @comment pthread.h
- @comment POSIX
- @deftypefun void pthread_cleanup_push (void (*@var{routine}) (void *), void *@var{arg})
- @code{pthread_cleanup_push} installs the @var{routine} function with
- argument @var{arg} as a cleanup handler. From this point on to the
- matching @code{pthread_cleanup_pop}, the function @var{routine} will be
- called with arguments @var{arg} when the thread terminates, either
- through @code{pthread_exit} or by cancellation. If several cleanup
- handlers are active at that point, they are called in LIFO order: the
- most recently installed handler is called first.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun void pthread_cleanup_pop (int @var{execute})
- @code{pthread_cleanup_pop} removes the most recently installed cleanup
- handler. If the @var{execute} argument is not 0, it also executes the
- handler, by calling the @var{routine} function with arguments
- @var{arg}. If the @var{execute} argument is 0, the handler is only
- removed but not executed.
- @end deftypefun
- Matching pairs of @code{pthread_cleanup_push} and
- @code{pthread_cleanup_pop} must occur in the same function, at the same
- level of block nesting. Actually, @code{pthread_cleanup_push} and
- @code{pthread_cleanup_pop} are macros, and the expansion of
- @code{pthread_cleanup_push} introduces an open brace @code{@{} with the
- matching closing brace @code{@}} being introduced by the expansion of the
- matching @code{pthread_cleanup_pop}.
- @comment pthread.h
- @comment GNU
- @deftypefun void pthread_cleanup_push_defer_np (void (*@var{routine}) (void *), void *@var{arg})
- @code{pthread_cleanup_push_defer_np} is a non-portable extension that
- combines @code{pthread_cleanup_push} and @code{pthread_setcanceltype}.
- It pushes a cleanup handler just as @code{pthread_cleanup_push} does,
- but also saves the current cancellation type and sets it to deferred
- cancellation. This ensures that the cleanup mechanism is effective even
- if the thread was initially in asynchronous cancellation mode.
- @end deftypefun
- @comment pthread.h
- @comment GNU
- @deftypefun void pthread_cleanup_pop_restore_np (int @var{execute})
- @code{pthread_cleanup_pop_restore_np} pops a cleanup handler introduced
- by @code{pthread_cleanup_push_defer_np}, and restores the cancellation
- type to its value at the time @code{pthread_cleanup_push_defer_np} was
- called.
- @end deftypefun
- @code{pthread_cleanup_push_defer_np} and
- @code{pthread_cleanup_pop_restore_np} must occur in matching pairs, at
- the same level of block nesting.
- The sequence
- @smallexample
- pthread_cleanup_push_defer_np(routine, arg);
- ...
- pthread_cleanup_pop_restore_np(execute);
- @end smallexample
- @noindent
- is functionally equivalent to (but more compact and efficient than)
- @smallexample
- @{
- int oldtype;
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
- pthread_cleanup_push(routine, arg);
- ...
- pthread_cleanup_pop(execute);
- pthread_setcanceltype(oldtype, NULL);
- @}
- @end smallexample
- @node Mutexes
- @section Mutexes
- A mutex is a MUTual EXclusion device, and is useful for protecting
- shared data structures from concurrent modifications, and implementing
- critical sections and monitors.
- A mutex has two possible states: unlocked (not owned by any thread),
- and locked (owned by one thread). A mutex can never be owned by two
- different threads simultaneously. A thread attempting to lock a mutex
- that is already locked by another thread is suspended until the owning
- thread unlocks the mutex first.
- None of the mutex functions is a cancellation point, not even
- @code{pthread_mutex_lock}, in spite of the fact that it can suspend a
- thread for arbitrary durations. This way, the status of mutexes at
- cancellation points is predictable, allowing cancellation handlers to
- unlock precisely those mutexes that need to be unlocked before the
- thread stops executing. Consequently, threads using deferred
- cancellation should never hold a mutex for extended periods of time.
- It is not safe to call mutex functions from a signal handler. In
- particular, calling @code{pthread_mutex_lock} or
- @code{pthread_mutex_unlock} from a signal handler may deadlock the
- calling thread.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_init (pthread_mutex_t *@var{mutex}, const pthread_mutexattr_t *@var{mutexattr})
- @code{pthread_mutex_init} initializes the mutex object pointed to by
- @var{mutex} according to the mutex attributes specified in @var{mutexattr}.
- If @var{mutexattr} is @code{NULL}, default attributes are used instead.
- The LinuxThreads implementation supports only one mutex attribute,
- the @var{mutex type}, which is either ``fast'', ``recursive'', or
- ``error checking''. The type of a mutex determines whether
- it can be locked again by a thread that already owns it.
- The default type is ``fast''.
- Variables of type @code{pthread_mutex_t} can also be initialized
- statically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (for
- timed mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (for
- recursive mutexes), @code{PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP}
- (for fast mutexes(, and @code{PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP}
- (for error checking mutexes).
- @code{pthread_mutex_init} always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_lock (pthread_mutex_t *mutex))
- @code{pthread_mutex_lock} locks the given mutex. If the mutex is
- currently unlocked, it becomes locked and owned by the calling thread,
- and @code{pthread_mutex_lock} returns immediately. If the mutex is
- already locked by another thread, @code{pthread_mutex_lock} suspends the
- calling thread until the mutex is unlocked.
- If the mutex is already locked by the calling thread, the behavior of
- @code{pthread_mutex_lock} depends on the type of the mutex. If the mutex
- is of the ``fast'' type, the calling thread is suspended. It will
- remain suspended forever, because no other thread can unlock the mutex.
- If the mutex is of the ``error checking'' type, @code{pthread_mutex_lock}
- returns immediately with the error code @code{EDEADLK}. If the mutex is
- of the ``recursive'' type, @code{pthread_mutex_lock} succeeds and
- returns immediately, recording the number of times the calling thread
- has locked the mutex. An equal number of @code{pthread_mutex_unlock}
- operations must be performed before the mutex returns to the unlocked
- state.
- @c This doesn't discuss PTHREAD_MUTEX_TIMED_NP mutex attributes. FIXME
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_trylock (pthread_mutex_t *@var{mutex})
- @code{pthread_mutex_trylock} behaves identically to
- @code{pthread_mutex_lock}, except that it does not block the calling
- thread if the mutex is already locked by another thread (or by the
- calling thread in the case of a ``fast'' mutex). Instead,
- @code{pthread_mutex_trylock} returns immediately with the error code
- @code{EBUSY}.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_timedlock (pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime})
- The @code{pthread_mutex_timedlock} is similar to the
- @code{pthread_mutex_lock} function but instead of blocking for in
- indefinite time if the mutex is locked by another thread, it returns
- when the time specified in @var{abstime} is reached.
- This function can only be used on standard (``timed'') and ``error
- checking'' mutexes. It behaves just like @code{pthread_mutex_lock} for
- all other types.
- If the mutex is successfully locked, the function returns zero. If the
- time specified in @var{abstime} is reached without the mutex being locked,
- @code{ETIMEDOUT} is returned.
- This function was introduced in the POSIX.1d revision of the POSIX standard.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_unlock (pthread_mutex_t *@var{mutex})
- @code{pthread_mutex_unlock} unlocks the given mutex. The mutex is
- assumed to be locked and owned by the calling thread on entrance to
- @code{pthread_mutex_unlock}. If the mutex is of the ``fast'' type,
- @code{pthread_mutex_unlock} always returns it to the unlocked state. If
- it is of the ``recursive'' type, it decrements the locking count of the
- mutex (number of @code{pthread_mutex_lock} operations performed on it by
- the calling thread), and only when this count reaches zero is the mutex
- actually unlocked.
- On ``error checking'' mutexes, @code{pthread_mutex_unlock} actually
- checks at run-time that the mutex is locked on entrance, and that it was
- locked by the same thread that is now calling
- @code{pthread_mutex_unlock}. If these conditions are not met,
- @code{pthread_mutex_unlock} returns @code{EPERM}, and the mutex remains
- unchanged. ``Fast'' and ``recursive'' mutexes perform no such checks,
- thus allowing a locked mutex to be unlocked by a thread other than its
- owner. This is non-portable behavior and must not be relied upon.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutex_destroy (pthread_mutex_t *@var{mutex})
- @code{pthread_mutex_destroy} destroys a mutex object, freeing the
- resources it might hold. The mutex must be unlocked on entrance. In the
- LinuxThreads implementation, no resources are associated with mutex
- objects, thus @code{pthread_mutex_destroy} actually does nothing except
- checking that the mutex is unlocked.
- If the mutex is locked by some thread, @code{pthread_mutex_destroy}
- returns @code{EBUSY}. Otherwise it returns 0.
- @end deftypefun
- If any of the above functions (except @code{pthread_mutex_init})
- is applied to an uninitialized mutex, they will simply return
- @code{EINVAL} and do nothing.
- A shared global variable @var{x} can be protected by a mutex as follows:
- @smallexample
- int x;
- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
- @end smallexample
- All accesses and modifications to @var{x} should be bracketed by calls to
- @code{pthread_mutex_lock} and @code{pthread_mutex_unlock} as follows:
- @smallexample
- pthread_mutex_lock(&mut);
- /* operate on x */
- pthread_mutex_unlock(&mut);
- @end smallexample
- Mutex attributes can be specified at mutex creation time, by passing a
- mutex attribute object as second argument to @code{pthread_mutex_init}.
- Passing @code{NULL} is equivalent to passing a mutex attribute object
- with all attributes set to their default values.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutexattr_init (pthread_mutexattr_t *@var{attr})
- @code{pthread_mutexattr_init} initializes the mutex attribute object
- @var{attr} and fills it with default values for the attributes.
- This function always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutexattr_destroy (pthread_mutexattr_t *@var{attr})
- @code{pthread_mutexattr_destroy} destroys a mutex attribute object,
- which must not be reused until it is
- reinitialized. @code{pthread_mutexattr_destroy} does nothing in the
- LinuxThreads implementation.
- This function always returns 0.
- @end deftypefun
- LinuxThreads supports only one mutex attribute: the mutex type, which is
- either @code{PTHREAD_MUTEX_ADAPTIVE_NP} for ``fast'' mutexes,
- @code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' mutexes,
- @code{PTHREAD_MUTEX_TIMED_NP} for ``timed'' mutexes, or
- @code{PTHREAD_MUTEX_ERRORCHECK_NP} for ``error checking'' mutexes. As
- the @code{NP} suffix indicates, this is a non-portable extension to the
- POSIX standard and should not be employed in portable programs.
- The mutex type determines what happens if a thread attempts to lock a
- mutex it already owns with @code{pthread_mutex_lock}. If the mutex is of
- the ``fast'' type, @code{pthread_mutex_lock} simply suspends the calling
- thread forever. If the mutex is of the ``error checking'' type,
- @code{pthread_mutex_lock} returns immediately with the error code
- @code{EDEADLK}. If the mutex is of the ``recursive'' type, the call to
- @code{pthread_mutex_lock} returns immediately with a success return
- code. The number of times the thread owning the mutex has locked it is
- recorded in the mutex. The owning thread must call
- @code{pthread_mutex_unlock} the same number of times before the mutex
- returns to the unlocked state.
- The default mutex type is ``timed'', that is, @code{PTHREAD_MUTEX_TIMED_NP}.
- @c This doesn't describe how a ``timed'' mutex behaves. FIXME
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutexattr_settype (pthread_mutexattr_t *@var{attr}, int @var{type})
- @code{pthread_mutexattr_settype} sets the mutex type attribute in
- @var{attr} to the value specified by @var{type}.
- If @var{type} is not @code{PTHREAD_MUTEX_ADAPTIVE_NP},
- @code{PTHREAD_MUTEX_RECURSIVE_NP}, @code{PTHREAD_MUTEX_TIMED_NP}, or
- @code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return
- @code{EINVAL} and leave @var{attr} unchanged.
- The standard Unix98 identifiers @code{PTHREAD_MUTEX_DEFAULT},
- @code{PTHREAD_MUTEX_NORMAL}, @code{PTHREAD_MUTEX_RECURSIVE},
- and @code{PTHREAD_MUTEX_ERRORCHECK} are also permitted.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_mutexattr_gettype (const pthread_mutexattr_t *@var{attr}, int *@var{type})
- @code{pthread_mutexattr_gettype} retrieves the current value of the
- mutex type attribute in @var{attr} and stores it in the location pointed
- to by @var{type}.
- This function always returns 0.
- @end deftypefun
- @node Condition Variables
- @section Condition Variables
- A condition (short for ``condition variable'') is a synchronization
- device that allows threads to suspend execution until some predicate on
- shared data is satisfied. The basic operations on conditions are: signal
- the condition (when the predicate becomes true), and wait for the
- condition, suspending the thread execution until another thread signals
- the condition.
- A condition variable must always be associated with a mutex, to avoid
- the race condition where a thread prepares to wait on a condition
- variable and another thread signals the condition just before the first
- thread actually waits on it.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_init (pthread_cond_t *@var{cond}, pthread_condattr_t *cond_@var{attr})
- @code{pthread_cond_init} initializes the condition variable @var{cond},
- using the condition attributes specified in @var{cond_attr}, or default
- attributes if @var{cond_attr} is @code{NULL}. The LinuxThreads
- implementation supports no attributes for conditions, hence the
- @var{cond_attr} parameter is actually ignored.
- Variables of type @code{pthread_cond_t} can also be initialized
- statically, using the constant @code{PTHREAD_COND_INITIALIZER}.
- This function always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_signal (pthread_cond_t *@var{cond})
- @code{pthread_cond_signal} restarts one of the threads that are waiting
- on the condition variable @var{cond}. If no threads are waiting on
- @var{cond}, nothing happens. If several threads are waiting on
- @var{cond}, exactly one is restarted, but it is not specified which.
- This function always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_broadcast (pthread_cond_t *@var{cond})
- @code{pthread_cond_broadcast} restarts all the threads that are waiting
- on the condition variable @var{cond}. Nothing happens if no threads are
- waiting on @var{cond}.
- This function always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_wait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex})
- @code{pthread_cond_wait} atomically unlocks the @var{mutex} (as per
- @code{pthread_unlock_mutex}) and waits for the condition variable
- @var{cond} to be signaled. The thread execution is suspended and does
- not consume any CPU time until the condition variable is signaled. The
- @var{mutex} must be locked by the calling thread on entrance to
- @code{pthread_cond_wait}. Before returning to the calling thread,
- @code{pthread_cond_wait} re-acquires @var{mutex} (as per
- @code{pthread_lock_mutex}).
- Unlocking the mutex and suspending on the condition variable is done
- atomically. Thus, if all threads always acquire the mutex before
- signaling the condition, this guarantees that the condition cannot be
- signaled (and thus ignored) between the time a thread locks the mutex
- and the time it waits on the condition variable.
- This function always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_timedwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime})
- @code{pthread_cond_timedwait} atomically unlocks @var{mutex} and waits
- on @var{cond}, as @code{pthread_cond_wait} does, but it also bounds the
- duration of the wait. If @var{cond} has not been signaled before time
- @var{abstime}, the mutex @var{mutex} is re-acquired and
- @code{pthread_cond_timedwait} returns the error code @code{ETIMEDOUT}.
- The wait can also be interrupted by a signal; in that case
- @code{pthread_cond_timedwait} returns @code{EINTR}.
- The @var{abstime} parameter specifies an absolute time, with the same
- origin as @code{time} and @code{gettimeofday}: an @var{abstime} of 0
- corresponds to 00:00:00 GMT, January 1, 1970.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_cond_destroy (pthread_cond_t *@var{cond})
- @code{pthread_cond_destroy} destroys the condition variable @var{cond},
- freeing the resources it might hold. If any threads are waiting on the
- condition variable, @code{pthread_cond_destroy} leaves @var{cond}
- untouched and returns @code{EBUSY}. Otherwise it returns 0, and
- @var{cond} must not be used again until it is reinitialized.
- In the LinuxThreads implementation, no resources are associated with
- condition variables, so @code{pthread_cond_destroy} actually does
- nothing.
- @end deftypefun
- @code{pthread_cond_wait} and @code{pthread_cond_timedwait} are
- cancellation points. If a thread is canceled while suspended in one of
- these functions, the thread immediately resumes execution, relocks the
- mutex specified by @var{mutex}, and finally executes the cancellation.
- Consequently, cleanup handlers are assured that @var{mutex} is locked
- when they are called.
- It is not safe to call the condition variable functions from a signal
- handler. In particular, calling @code{pthread_cond_signal} or
- @code{pthread_cond_broadcast} from a signal handler may deadlock the
- calling thread.
- Consider two shared variables @var{x} and @var{y}, protected by the
- mutex @var{mut}, and a condition variable @var{cond} that is to be
- signaled whenever @var{x} becomes greater than @var{y}.
- @smallexample
- int x,y;
- pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- @end smallexample
- Waiting until @var{x} is greater than @var{y} is performed as follows:
- @smallexample
- pthread_mutex_lock(&mut);
- while (x <= y) @{
- pthread_cond_wait(&cond, &mut);
- @}
- /* operate on x and y */
- pthread_mutex_unlock(&mut);
- @end smallexample
- Modifications on @var{x} and @var{y} that may cause @var{x} to become greater than
- @var{y} should signal the condition if needed:
- @smallexample
- pthread_mutex_lock(&mut);
- /* modify x and y */
- if (x > y) pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&mut);
- @end smallexample
- If it can be proved that at most one waiting thread needs to be waken
- up (for instance, if there are only two threads communicating through
- @var{x} and @var{y}), @code{pthread_cond_signal} can be used as a slightly more
- efficient alternative to @code{pthread_cond_broadcast}. In doubt, use
- @code{pthread_cond_broadcast}.
- To wait for @var{x} to becomes greater than @var{y} with a timeout of 5
- seconds, do:
- @smallexample
- struct timeval now;
- struct timespec timeout;
- int retcode;
- pthread_mutex_lock(&mut);
- gettimeofday(&now);
- timeout.tv_sec = now.tv_sec + 5;
- timeout.tv_nsec = now.tv_usec * 1000;
- retcode = 0;
- while (x <= y && retcode != ETIMEDOUT) @{
- retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
- @}
- if (retcode == ETIMEDOUT) @{
- /* timeout occurred */
- @} else @{
- /* operate on x and y */
- @}
- pthread_mutex_unlock(&mut);
- @end smallexample
- Condition attributes can be specified at condition creation time, by
- passing a condition attribute object as second argument to
- @code{pthread_cond_init}. Passing @code{NULL} is equivalent to passing
- a condition attribute object with all attributes set to their default
- values.
- The LinuxThreads implementation supports no attributes for
- conditions. The functions on condition attributes are included only for
- compliance with the POSIX standard.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_condattr_init (pthread_condattr_t *@var{attr})
- @deftypefunx int pthread_condattr_destroy (pthread_condattr_t *@var{attr})
- @code{pthread_condattr_init} initializes the condition attribute object
- @var{attr} and fills it with default values for the attributes.
- @code{pthread_condattr_destroy} destroys the condition attribute object
- @var{attr}.
- Both functions do nothing in the LinuxThreads implementation.
- @code{pthread_condattr_init} and @code{pthread_condattr_destroy} always
- return 0.
- @end deftypefun
- @node POSIX Semaphores
- @section POSIX Semaphores
- @vindex SEM_VALUE_MAX
- Semaphores are counters for resources shared between threads. The
- basic operations on semaphores are: increment the counter atomically,
- and wait until the counter is non-null and decrement it atomically.
- Semaphores have a maximum value past which they cannot be incremented.
- The macro @code{SEM_VALUE_MAX} is defined to be this maximum value. In
- the GNU C library, @code{SEM_VALUE_MAX} is equal to @code{INT_MAX}
- (@pxref{Range of Type}), but it may be much smaller on other systems.
- The pthreads library implements POSIX 1003.1b semaphores. These should
- not be confused with System V semaphores (@code{ipc}, @code{semctl} and
- @code{semop}).
- @c !!! SysV IPC is not doc'd at all in our manual
- All the semaphore functions and macros are defined in @file{semaphore.h}.
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value})
- @code{sem_init} initializes the semaphore object pointed to by
- @var{sem}. The count associated with the semaphore is set initially to
- @var{value}. The @var{pshared} argument indicates whether the semaphore
- is local to the current process (@var{pshared} is zero) or is to be
- shared between several processes (@var{pshared} is not zero).
- On success @code{sem_init} returns 0. On failure it returns -1 and sets
- @var{errno} to one of the following values:
- @table @code
- @item EINVAL
- @var{value} exceeds the maximal counter value @code{SEM_VALUE_MAX}
- @item ENOSYS
- @var{pshared} is not zero. LinuxThreads currently does not support
- process-shared semaphores. (This will eventually change.)
- @end table
- @end deftypefun
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_destroy (sem_t * @var{sem})
- @code{sem_destroy} destroys a semaphore object, freeing the resources it
- might hold. If any threads are waiting on the semaphore when
- @code{sem_destroy} is called, it fails and sets @var{errno} to
- @code{EBUSY}.
- In the LinuxThreads implementation, no resources are associated with
- semaphore objects, thus @code{sem_destroy} actually does nothing except
- checking that no thread is waiting on the semaphore. This will change
- when process-shared semaphores are implemented.
- @end deftypefun
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_wait (sem_t * @var{sem})
- @code{sem_wait} suspends the calling thread until the semaphore pointed
- to by @var{sem} has non-zero count. It then atomically decreases the
- semaphore count.
- @code{sem_wait} is a cancellation point. It always returns 0.
- @end deftypefun
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_trywait (sem_t * @var{sem})
- @code{sem_trywait} is a non-blocking variant of @code{sem_wait}. If the
- semaphore pointed to by @var{sem} has non-zero count, the count is
- atomically decreased and @code{sem_trywait} immediately returns 0. If
- the semaphore count is zero, @code{sem_trywait} immediately returns -1
- and sets errno to @code{EAGAIN}.
- @end deftypefun
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_post (sem_t * @var{sem})
- @code{sem_post} atomically increases the count of the semaphore pointed to
- by @var{sem}. This function never blocks.
- @c !!! This para appears not to agree with the code.
- On processors supporting atomic compare-and-swap (Intel 486, Pentium and
- later, Alpha, PowerPC, MIPS II, Motorola 68k, Ultrasparc), the
- @code{sem_post} function is can safely be called from signal handlers.
- This is the only thread synchronization function provided by POSIX
- threads that is async-signal safe. On the Intel 386 and earlier Sparc
- chips, the current LinuxThreads implementation of @code{sem_post} is not
- async-signal safe, because the hardware does not support the required
- atomic operations.
- @code{sem_post} always succeeds and returns 0, unless the semaphore
- count would exceed @code{SEM_VALUE_MAX} after being incremented. In
- that case @code{sem_post} returns -1 and sets @var{errno} to
- @code{EINVAL}. The semaphore count is left unchanged.
- @end deftypefun
- @comment semaphore.h
- @comment POSIX
- @deftypefun int sem_getvalue (sem_t * @var{sem}, int * @var{sval})
- @code{sem_getvalue} stores in the location pointed to by @var{sval} the
- current count of the semaphore @var{sem}. It always returns 0.
- @end deftypefun
- @node Thread-Specific Data
- @section Thread-Specific Data
- Programs often need global or static variables that have different
- values in different threads. Since threads share one memory space, this
- cannot be achieved with regular variables. Thread-specific data is the
- POSIX threads answer to this need.
- Each thread possesses a private memory block, the thread-specific data
- area, or TSD area for short. This area is indexed by TSD keys. The TSD
- area associates values of type @code{void *} to TSD keys. TSD keys are
- common to all threads, but the value associated with a given TSD key can
- be different in each thread.
- For concreteness, the TSD areas can be viewed as arrays of @code{void *}
- pointers, TSD keys as integer indices into these arrays, and the value
- of a TSD key as the value of the corresponding array element in the
- calling thread.
- When a thread is created, its TSD area initially associates @code{NULL}
- with all keys.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*destr_function) (void *))
- @code{pthread_key_create} allocates a new TSD key. The key is stored in
- the location pointed to by @var{key}. There is a limit of
- @code{PTHREAD_KEYS_MAX} on the number of keys allocated at a given
- time. The value initially associated with the returned key is
- @code{NULL} in all currently executing threads.
- The @var{destr_function} argument, if not @code{NULL}, specifies a
- destructor function associated with the key. When a thread terminates
- via @code{pthread_exit} or by cancellation, @var{destr_function} is
- called on the value associated with the key in that thread. The
- @var{destr_function} is not called if a key is deleted with
- @code{pthread_key_delete} or a value is changed with
- @code{pthread_setspecific}. The order in which destructor functions are
- called at thread termination time is unspecified.
- Before the destructor function is called, the @code{NULL} value is
- associated with the key in the current thread. A destructor function
- might, however, re-associate non-@code{NULL} values to that key or some
- other key. To deal with this, if after all the destructors have been
- called for all non-@code{NULL} values, there are still some
- non-@code{NULL} values with associated destructors, then the process is
- repeated. The LinuxThreads implementation stops the process after
- @code{PTHREAD_DESTRUCTOR_ITERATIONS} iterations, even if some
- non-@code{NULL} values with associated descriptors remain. Other
- implementations may loop indefinitely.
- @code{pthread_key_create} returns 0 unless @code{PTHREAD_KEYS_MAX} keys
- have already been allocated, in which case it fails and returns
- @code{EAGAIN}.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_key_delete (pthread_key_t @var{key})
- @code{pthread_key_delete} deallocates a TSD key. It does not check
- whether non-@code{NULL} values are associated with that key in the
- currently executing threads, nor call the destructor function associated
- with the key.
- If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise
- it returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{pointer})
- @code{pthread_setspecific} changes the value associated with @var{key}
- in the calling thread, storing the given @var{pointer} instead.
- If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise
- it returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun {void *} pthread_getspecific (pthread_key_t @var{key})
- @code{pthread_getspecific} returns the value currently associated with
- @var{key} in the calling thread.
- If there is no such key @var{key}, it returns @code{NULL}.
- @end deftypefun
- The following code fragment allocates a thread-specific array of 100
- characters, with automatic reclaimation at thread exit:
- @smallexample
- /* Key for the thread-specific buffer */
- static pthread_key_t buffer_key;
- /* Once-only initialisation of the key */
- static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
- /* Allocate the thread-specific buffer */
- void buffer_alloc(void)
- @{
- pthread_once(&buffer_key_once, buffer_key_alloc);
- pthread_setspecific(buffer_key, malloc(100));
- @}
- /* Return the thread-specific buffer */
- char * get_buffer(void)
- @{
- return (char *) pthread_getspecific(buffer_key);
- @}
- /* Allocate the key */
- static void buffer_key_alloc()
- @{
- pthread_key_create(&buffer_key, buffer_destroy);
- @}
- /* Free the thread-specific buffer */
- static void buffer_destroy(void * buf)
- @{
- free(buf);
- @}
- @end smallexample
- @node Threads and Signal Handling
- @section Threads and Signal Handling
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_sigmask (int @var{how}, const sigset_t *@var{newmask}, sigset_t *@var{oldmask})
- @code{pthread_sigmask} changes the signal mask for the calling thread as
- described by the @var{how} and @var{newmask} arguments. If @var{oldmask}
- is not @code{NULL}, the previous signal mask is stored in the location
- pointed to by @var{oldmask}.
- The meaning of the @var{how} and @var{newmask} arguments is the same as
- for @code{sigprocmask}. If @var{how} is @code{SIG_SETMASK}, the signal
- mask is set to @var{newmask}. If @var{how} is @code{SIG_BLOCK}, the
- signals specified to @var{newmask} are added to the current signal mask.
- If @var{how} is @code{SIG_UNBLOCK}, the signals specified to
- @var{newmask} are removed from the current signal mask.
- Recall that signal masks are set on a per-thread basis, but signal
- actions and signal handlers, as set with @code{sigaction}, are shared
- between all threads.
- The @code{pthread_sigmask} function returns 0 on success, and one of the
- following error codes on error:
- @table @code
- @item EINVAL
- @var{how} is not one of @code{SIG_SETMASK}, @code{SIG_BLOCK}, or @code{SIG_UNBLOCK}
- @item EFAULT
- @var{newmask} or @var{oldmask} point to invalid addresses
- @end table
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_kill (pthread_t @var{thread}, int @var{signo})
- @code{pthread_kill} sends signal number @var{signo} to the thread
- @var{thread}. The signal is delivered and handled as described in
- @ref{Signal Handling}.
- @code{pthread_kill} returns 0 on success, one of the following error codes
- on error:
- @table @code
- @item EINVAL
- @var{signo} is not a valid signal number
- @item ESRCH
- The thread @var{thread} does not exist (e.g. it has already terminated)
- @end table
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int sigwait (const sigset_t *@var{set}, int *@var{sig})
- @code{sigwait} suspends the calling thread until one of the signals in
- @var{set} is delivered to the calling thread. It then stores the number
- of the signal received in the location pointed to by @var{sig} and
- returns. The signals in @var{set} must be blocked and not ignored on
- entrance to @code{sigwait}. If the delivered signal has a signal handler
- function attached, that function is @emph{not} called.
- @code{sigwait} is a cancellation point. It always returns 0.
- @end deftypefun
- For @code{sigwait} to work reliably, the signals being waited for must be
- blocked in all threads, not only in the calling thread, since
- otherwise the POSIX semantics for signal delivery do not guarantee
- that it's the thread doing the @code{sigwait} that will receive the signal.
- The best way to achieve this is block those signals before any threads
- are created, and never unblock them in the program other than by
- calling @code{sigwait}.
- Signal handling in LinuxThreads departs significantly from the POSIX
- standard. According to the standard, ``asynchronous'' (external) signals
- are addressed to the whole process (the collection of all threads),
- which then delivers them to one particular thread. The thread that
- actually receives the signal is any thread that does not currently block
- the signal.
- In LinuxThreads, each thread is actually a kernel process with its own
- PID, so external signals are always directed to one particular thread.
- If, for instance, another thread is blocked in @code{sigwait} on that
- signal, it will not be restarted.
- The LinuxThreads implementation of @code{sigwait} installs dummy signal
- handlers for the signals in @var{set} for the duration of the
- wait. Since signal handlers are shared between all threads, other
- threads must not attach their own signal handlers to these signals, or
- alternatively they should all block these signals (which is recommended
- anyway).
- @node Threads and Fork
- @section Threads and Fork
- It's not intuitively obvious what should happen when a multi-threaded POSIX
- process calls @code{fork}. Not only are the semantics tricky, but you may
- need to write code that does the right thing at fork time even if that code
- doesn't use the @code{fork} function. Moreover, you need to be aware of
- interaction between @code{fork} and some library features like
- @code{pthread_once} and stdio streams.
- When @code{fork} is called by one of the threads of a process, it creates a new
- process which is copy of the calling process. Effectively, in addition to
- copying certain system objects, the function takes a snapshot of the memory
- areas of the parent process, and creates identical areas in the child.
- To make matters more complicated, with threads it's possible for two or more
- threads to concurrently call fork to create two or more child processes.
- The child process has a copy of the address space of the parent, but it does
- not inherit any of its threads. Execution of the child process is carried out
- by a new thread which returns from @code{fork} function with a return value of
- zero; it is the only thread in the child process. Because threads are not
- inherited across fork, issues arise. At the time of the call to @code{fork},
- threads in the parent process other than the one calling @code{fork} may have
- been executing critical regions of code. As a result, the child process may
- get a copy of objects that are not in a well-defined state. This potential
- problem affects all components of the program.
- Any program component which will continue being used in a child process must
- correctly handle its state during @code{fork}. For this purpose, the POSIX
- interface provides the special function @code{pthread_atfork} for installing
- pointers to handler functions which are called from within @code{fork}.
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_atfork (void (*@var{prepare})(void), void (*@var{parent})(void), void (*@var{child})(void))
- @code{pthread_atfork} registers handler functions to be called just
- before and just after a new process is created with @code{fork}. The
- @var{prepare} handler will be called from the parent process, just
- before the new process is created. The @var{parent} handler will be
- called from the parent process, just before @code{fork} returns. The
- @var{child} handler will be called from the child process, just before
- @code{fork} returns.
- @code{pthread_atfork} returns 0 on success and a non-zero error code on
- error.
- One or more of the three handlers @var{prepare}, @var{parent} and
- @var{child} can be given as @code{NULL}, meaning that no handler needs
- to be called at the corresponding point.
- @code{pthread_atfork} can be called several times to install several
- sets of handlers. At @code{fork} time, the @var{prepare} handlers are
- called in LIFO order (last added with @code{pthread_atfork}, first
- called before @code{fork}), while the @var{parent} and @var{child}
- handlers are called in FIFO order (first added, first called).
- If there is insufficient memory available to register the handlers,
- @code{pthread_atfork} fails and returns @code{ENOMEM}. Otherwise it
- returns 0.
- The functions @code{fork} and @code{pthread_atfork} must not be regarded as
- reentrant from the context of the handlers. That is to say, if a
- @code{pthread_atfork} handler invoked from within @code{fork} calls
- @code{pthread_atfork} or @code{fork}, the behavior is undefined.
- Registering a triplet of handlers is an atomic operation with respect to fork.
- If new handlers are registered at about the same time as a fork occurs, either
- all three handlers will be called, or none of them will be called.
- The handlers are inherited by the child process, and there is no
- way to remove them, short of using @code{exec} to load a new
- pocess image.
- @end deftypefun
- To understand the purpose of @code{pthread_atfork}, recall that
- @code{fork} duplicates the whole memory space, including mutexes in
- their current locking state, but only the calling thread: other threads
- are not running in the child process. The mutexes are not usable after
- the @code{fork} and must be initialized with @code{pthread_mutex_init}
- in the child process. This is a limitation of the current
- implementation and might or might not be present in future versions.
- To avoid this, install handlers with @code{pthread_atfork} as follows: have the
- @var{prepare} handler lock the mutexes (in locking order), and the
- @var{parent} handler unlock the mutexes. The @var{child} handler should reset
- the mutexes using @code{pthread_mutex_init}, as well as any other
- synchronization objects such as condition variables.
- Locking the global mutexes before the fork ensures that all other threads are
- locked out of the critical regions of code protected by those mutexes. Thus
- when @code{fork} takes a snapshot of the parent's address space, that snapshot
- will copy valid, stable data. Resetting the synchronization objects in the
- child process will ensure they are properly cleansed of any artifacts from the
- threading subsystem of the parent process. For example, a mutex may inherit
- a wait queue of threads waiting for the lock; this wait queue makes no sense
- in the child process. Initializing the mutex takes care of this.
- @node Streams and Fork
- @section Streams and Fork
- The GNU standard I/O library has an internal mutex which guards the internal
- linked list of all standard C FILE objects. This mutex is properly taken care
- of during @code{fork} so that the child receives an intact copy of the list.
- This allows the @code{fopen} function, and related stream-creating functions,
- to work correctly in the child process, since these functions need to insert
- into the list.
- However, the individual stream locks are not completely taken care of. Thus
- unless the multithreaded application takes special precautions in its use of
- @code{fork}, the child process might not be able to safely use the streams that
- it inherited from the parent. In general, for any given open stream in the
- parent that is to be used by the child process, the application must ensure
- that that stream is not in use by another thread when @code{fork} is called.
- Otherwise an inconsistent copy of the stream object be produced. An easy way to
- ensure this is to use @code{flockfile} to lock the stream prior to calling
- @code{fork} and then unlock it with @code{funlockfile} inside the parent
- process, provided that the parent's threads properly honor these locks.
- Nothing special needs to be done in the child process, since the library
- internally resets all stream locks.
- Note that the stream locks are not shared between the parent and child.
- For example, even if you ensure that, say, the stream @code{stdout} is properly
- treated and can be safely used in the child, the stream locks do not provide
- an exclusion mechanism between the parent and child. If both processes write
- to @code{stdout}, strangely interleaved output may result regardless of
- the explicit use of @code{flockfile} or implicit locks.
- Also note that these provisions are a GNU extension; other systems might not
- provide any way for streams to be used in the child of a multithreaded process.
- POSIX requires that such a child process confines itself to calling only
- asynchronous safe functions, which excludes much of the library, including
- standard I/O.
- @node Miscellaneous Thread Functions
- @section Miscellaneous Thread Functions
- @comment pthread.h
- @comment POSIX
- @deftypefun {pthread_t} pthread_self (@var{void})
- @code{pthread_self} returns the thread identifier for the calling thread.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_equal (pthread_t thread1, pthread_t thread2)
- @code{pthread_equal} determines if two thread identifiers refer to the same
- thread.
- A non-zero value is returned if @var{thread1} and @var{thread2} refer to
- the same thread. Otherwise, 0 is returned.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_detach (pthread_t @var{th})
- @code{pthread_detach} puts the thread @var{th} in the detached
- state. This guarantees that the memory resources consumed by @var{th}
- will be freed immediately when @var{th} terminates. However, this
- prevents other threads from synchronizing on the termination of @var{th}
- using @code{pthread_join}.
- A thread can be created initially in the detached state, using the
- @code{detachstate} attribute to @code{pthread_create}. In contrast,
- @code{pthread_detach} applies to threads created in the joinable state,
- and which need to be put in the detached state later.
- After @code{pthread_detach} completes, subsequent attempts to perform
- @code{pthread_join} on @var{th} will fail. If another thread is already
- joining the thread @var{th} at the time @code{pthread_detach} is called,
- @code{pthread_detach} does nothing and leaves @var{th} in the joinable
- state.
- On success, 0 is returned. On error, one of the following codes is
- returned:
- @table @code
- @item ESRCH
- No thread could be found corresponding to that specified by @var{th}
- @item EINVAL
- The thread @var{th} is already in the detached state
- @end table
- @end deftypefun
- @comment pthread.h
- @comment GNU
- @deftypefun void pthread_kill_other_threads_np (@var{void})
- @code{pthread_kill_other_threads_np} is a non-portable LinuxThreads extension.
- It causes all threads in the program to terminate immediately, except
- the calling thread which proceeds normally. It is intended to be
- called just before a thread calls one of the @code{exec} functions,
- e.g. @code{execve}.
- Termination of the other threads is not performed through
- @code{pthread_cancel} and completely bypasses the cancellation
- mechanism. Hence, the current settings for cancellation state and
- cancellation type are ignored, and the cleanup handlers are not
- executed in the terminated threads.
- According to POSIX 1003.1c, a successful @code{exec*} in one of the
- threads should automatically terminate all other threads in the program.
- This behavior is not yet implemented in LinuxThreads. Calling
- @code{pthread_kill_other_threads_np} before @code{exec*} achieves much
- of the same behavior, except that if @code{exec*} ultimately fails, then
- all other threads are already killed.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_once (pthread_once_t *once_@var{control}, void (*@var{init_routine}) (void))
- The purpose of @code{pthread_once} is to ensure that a piece of
- initialization code is executed at most once. The @var{once_control}
- argument points to a static or extern variable statically initialized
- to @code{PTHREAD_ONCE_INIT}.
- The first time @code{pthread_once} is called with a given
- @var{once_control} argument, it calls @var{init_routine} with no
- argument and changes the value of the @var{once_control} variable to
- record that initialization has been performed. Subsequent calls to
- @code{pthread_once} with the same @code{once_control} argument do
- nothing.
- If a thread is cancelled while executing @var{init_routine}
- the state of the @var{once_control} variable is reset so that
- a future call to @code{pthread_once} will call the routine again.
- If the process forks while one or more threads are executing
- @code{pthread_once} initialization routines, the states of their respective
- @var{once_control} variables will appear to be reset in the child process so
- that if the child calls @code{pthread_once}, the routines will be executed.
- @code{pthread_once} always returns 0.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_setschedparam (pthread_t target_@var{thread}, int @var{policy}, const struct sched_param *@var{param})
- @code{pthread_setschedparam} sets the scheduling parameters for the
- thread @var{target_thread} as indicated by @var{policy} and
- @var{param}. @var{policy} can be either @code{SCHED_OTHER} (regular,
- non-realtime scheduling), @code{SCHED_RR} (realtime, round-robin) or
- @code{SCHED_FIFO} (realtime, first-in first-out). @var{param} specifies
- the scheduling priority for the two realtime policies. See
- @code{sched_setpolicy} for more information on scheduling policies.
- The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO}
- are available only to processes with superuser privileges.
- On success, @code{pthread_setschedparam} returns 0. On error it returns
- one of the following codes:
- @table @code
- @item EINVAL
- @var{policy} is not one of @code{SCHED_OTHER}, @code{SCHED_RR},
- @code{SCHED_FIFO}, or the priority value specified by @var{param} is not
- valid for the specified policy
- @item EPERM
- Realtime scheduling was requested but the calling process does not have
- sufficient privileges.
- @item ESRCH
- The @var{target_thread} is invalid or has already terminated
- @item EFAULT
- @var{param} points outside the process memory space
- @end table
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_getschedparam (pthread_t target_@var{thread}, int *@var{policy}, struct sched_param *@var{param})
- @code{pthread_getschedparam} retrieves the scheduling policy and
- scheduling parameters for the thread @var{target_thread} and stores them
- in the locations pointed to by @var{policy} and @var{param},
- respectively.
- @code{pthread_getschedparam} returns 0 on success, or one of the
- following error codes on failure:
- @table @code
- @item ESRCH
- The @var{target_thread} is invalid or has already terminated.
- @item EFAULT
- @var{policy} or @var{param} point outside the process memory space.
- @end table
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_setconcurrency (int @var{level})
- @code{pthread_setconcurrency} is unused in LinuxThreads due to the lack
- of a mapping of user threads to kernel threads. It exists for source
- compatibility. It does store the value @var{level} so that it can be
- returned by a subsequent call to @code{pthread_getconcurrency}. It takes
- no other action however.
- @end deftypefun
- @comment pthread.h
- @comment POSIX
- @deftypefun int pthread_getconcurrency ()
- @code{pthread_getconcurrency} is unused in LinuxThreads due to the lack
- of a mapping of user threads to kernel threads. It exists for source
- compatibility. However, it will return the value that was set by the
- last call to @code{pthread_setconcurrency}.
- @end deftypefun
|