📄 linuxthreads.texi
字号:
already locked by another thread, @code{pthread_mutex_lock} suspends thecalling 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 mutexis of the ``fast'' type, the calling thread is suspended. It willremain 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 isof the ``recursive'' type, @code{pthread_mutex_lock} succeeds andreturns immediately, recording the number of times the calling threadhas locked the mutex. An equal number of @code{pthread_mutex_unlock}operations must be performed before the mutex returns to the unlockedstate.@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 callingthread if the mutex is already locked by another thread (or by thecalling 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 inindefinite time if the mutex is locked by another thread, it returnswhen the time specified in @var{abstime} is reached.This function can only be used on standard (``timed'') and ``errorchecking'' mutexes. It behaves just like @code{pthread_mutex_lock} forall other types.If the mutex is successfully locked, the function returns zero. If thetime 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 isassumed 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. Ifit is of the ``recursive'' type, it decrements the locking count of themutex (number of @code{pthread_mutex_lock} operations performed on it bythe calling thread), and only when this count reaches zero is the mutexactually unlocked.On ``error checking'' mutexes, @code{pthread_mutex_unlock} actuallychecks at run-time that the mutex is locked on entrance, and that it waslocked 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 remainsunchanged. ``Fast'' and ``recursive'' mutexes perform no such checks,thus allowing a locked mutex to be unlocked by a thread other than itsowner. 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 theresources it might hold. The mutex must be unlocked on entrance. In theLinuxThreads implementation, no resources are associated with mutexobjects, thus @code{pthread_mutex_destroy} actually does nothing exceptchecking 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 deftypefunIf 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:@smallexampleint x;pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;@end smallexampleAll accesses and modifications to @var{x} should be bracketed by calls to@code{pthread_mutex_lock} and @code{pthread_mutex_unlock} as follows:@smallexamplepthread_mutex_lock(&mut);/* operate on x */pthread_mutex_unlock(&mut);@end smallexampleMutex attributes can be specified at mutex creation time, by passing amutex attribute object as second argument to @code{pthread_mutex_init}.Passing @code{NULL} is equivalent to passing a mutex attribute objectwith 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 isreinitialized. @code{pthread_mutexattr_destroy} does nothing in theLinuxThreads implementation.This function always returns 0.@end deftypefunLinuxThreads supports only one mutex attribute: the mutex type, which iseither @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. Asthe @code{NP} suffix indicates, this is a non-portable extension to thePOSIX standard and should not be employed in portable programs.The mutex type determines what happens if a thread attempts to lock amutex it already owns with @code{pthread_mutex_lock}. If the mutex is ofthe ``fast'' type, @code{pthread_mutex_lock} simply suspends the callingthread 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 returncode. The number of times the thread owning the mutex has locked it isrecorded in the mutex. The owning thread must call@code{pthread_mutex_unlock} the same number of times before the mutexreturns 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 themutex type attribute in @var{attr} and stores it in the location pointedto by @var{type}.This function always returns 0.@end deftypefun@node Condition Variables@section Condition VariablesA condition (short for ``condition variable'') is a synchronizationdevice that allows threads to suspend execution until some predicate onshared data is satisfied. The basic operations on conditions are: signalthe condition (when the predicate becomes true), and wait for thecondition, suspending the thread execution until another thread signalsthe condition.A condition variable must always be associated with a mutex, to avoidthe race condition where a thread prepares to wait on a conditionvariable and another thread signals the condition just before the firstthread 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 defaultattributes if @var{cond_attr} is @code{NULL}. The LinuxThreadsimplementation supports no attributes for conditions, hence the@var{cond_attr} parameter is actually ignored.Variables of type @code{pthread_cond_t} can also be initializedstatically, 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 waitingon 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 waitingon the condition variable @var{cond}. Nothing happens if no threads arewaiting 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 doesnot 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 doneatomically. Thus, if all threads always acquire the mutex beforesignaling the condition, this guarantees that the condition cannot besignaled (and thus ignored) between the time a thread locks the mutexand 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 waitson @var{cond}, as @code{pthread_cond_wait} does, but it also bounds theduration 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 sameorigin as @code{time} and @code{gettimeofday}: an @var{abstime} of 0corresponds 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 thecondition 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 withcondition variables, so @code{pthread_cond_destroy} actually doesnothing.@end deftypefun@code{pthread_cond_wait} and @code{pthread_cond_timedwait} arecancellation points. If a thread is canceled while suspended in one ofthese functions, the thread immediately resumes execution, relocks themutex specified by @var{mutex}, and finally executes the cancellation.Consequently, cleanup handlers are assured that @var{mutex} is lockedwhen they are called.It is not safe to call the condition variable functions from a signalhandler. In particular, calling @code{pthread_cond_signal} or@code{pthread_cond_broadcast} from a signal handler may deadlock thecalling thread.Consider two shared variables @var{x} and @var{y}, protected by themutex @var{mut}, and a condition variable @var{cond} that is to besignaled whenever @var{x} becomes greater than @var{y}.@smallexampleint x,y;pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;@end smallexampleWaiting until @var{x} is greater than @var{y} is performed as follows:@smallexamplepthread_mutex_lock(&mut);while (x <= y) @{ pthread_cond_wait(&cond, &mut);@}/* operate on x and y */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -