⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linuxthreads.texi

📁 Axis 221 camera embedded programing interface
💻 TEXI
📖 第 1 页 / 共 4 页
字号:
@end deftypefun@comment pthread.h@comment POSIX@deftypefun void pthread_testcancel (@var{void})@code{pthread_testcancel} does nothing except testing for pendingcancellation and executing it. Its purpose is to introduce explicitchecks for cancellation in long sequences of code that do not callcancellation point functions otherwise.@end deftypefun@node Cleanup Handlers@section Cleanup HandlersCleanup handlers are functions that get called when a thread terminates,either by calling @code{pthread_exit} or because ofcancellation. Cleanup handlers are installed and removed following astack-like discipline.The purpose of cleanup handlers is to free the resources that a threadmay hold at the time it terminates. In particular, if a thread exits oris cancelled while it owns a locked mutex, the mutex will remain lockedforever and prevent other threads from executing normally. The best wayto avoid this is, just before locking the mutex, to install a cleanuphandler whose effect is to unlock the mutex. Cleanup handlers can beused similarly to free blocks allocated with @code{malloc} or close filedescriptors on thread termination.Here is how to lock a mutex @var{mut} in such a way that it will beunlocked if the thread is canceled while @var{mut} is locked:@smallexamplepthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);pthread_mutex_lock(&mut);/* do some work */pthread_mutex_unlock(&mut);pthread_cleanup_pop(0);@end smallexampleEquivalently, the last two lines can be replaced by@smallexamplepthread_cleanup_pop(1);@end smallexampleNotice that the code above is safe only in deferred cancellation mode(see @code{pthread_setcanceltype}). In asynchronous cancellation mode, acancellation 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 tryingto unlock a mutex not locked by the current thread. This is the mainreason 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 themutex:@smallexamplepthread_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 smallexampleThe 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}:@smallexamplepthread_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 withargument @var{arg} as a cleanup handler. From this point on to thematching @code{pthread_cleanup_pop}, the function @var{routine} will becalled with arguments @var{arg} when the thread terminates, eitherthrough @code{pthread_exit} or by cancellation. If several cleanuphandlers are active at that point, they are called in LIFO order: themost 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 cleanuphandler. If the @var{execute} argument is not 0, it also executes thehandler, by calling the @var{routine} function with arguments@var{arg}. If the @var{execute} argument is 0, the handler is onlyremoved but not executed.@end deftypefunMatching pairs of @code{pthread_cleanup_push} and@code{pthread_cleanup_pop} must occur in the same function, at the samelevel 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 thematching closing brace @code{@}} being introduced by the expansion of thematching @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 thatcombines @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 deferredcancellation. This ensures that the cleanup mechanism is effective evenif 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 introducedby @code{pthread_cleanup_push_defer_np}, and restores the cancellationtype to its value at the time @code{pthread_cleanup_push_defer_np} wascalled.@end deftypefun@code{pthread_cleanup_push_defer_np} and@code{pthread_cleanup_pop_restore_np} must occur in matching pairs, atthe same level of block nesting.The sequence@smallexamplepthread_cleanup_push_defer_np(routine, arg);...pthread_cleanup_pop_defer_np(execute);@end smallexample@noindentis 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 MutexesA mutex is a MUTual EXclusion device, and is useful for protectingshared data structures from concurrent modifications, and implementingcritical 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 twodifferent threads simultaneously. A thread attempting to lock a mutexthat is already locked by another thread is suspended until the owningthread 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 athread for arbitrary durations. This way, the status of mutexes atcancellation points is predictable, allowing cancellation handlers tounlock precisely those mutexes that need to be unlocked before thethread stops executing. Consequently, threads using deferredcancellation should never hold a mutex for extended periods of time.It is not safe to call mutex functions from a signal handler.  Inparticular, calling @code{pthread_mutex_lock} or@code{pthread_mutex_unlock} from a signal handler may deadlock thecalling 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 kind}, which is either ``fast'', ``recursive'', or``error checking''. The kind of a mutex determines whetherit can be locked again by a thread that already owns it.The default kind is ``fast''.Variables of type @code{pthread_mutex_t} can also be initializedstatically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (forfast mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (forrecursive 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 iscurrently unlocked, it becomes locked and owned by the calling thread,and @code{pthread_mutex_lock} returns immediately. If the mutex isalready 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 kind of the mutex. If the mutexis of the ``fast'' kind, 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'' kind, @code{pthread_mutex_lock}returns immediately with the error code @code{EDEADLK}.  If the mutex isof the ``recursive'' kind, @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.@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_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'' kind,@code{pthread_mutex_unlock} always returns it to the unlocked state. Ifit is of the ``recursive'' kind, 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 kind, which iseither @code{PTHREAD_MUTEX_FAST_NP} for ``fast'' mutexes,@code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' 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 kind determines what happens if a thread attempts to lock amutex it already owns with @code{pthread_mutex_lock}. If the mutex is ofthe ``fast'' kind, @code{pthread_mutex_lock} simply suspends the callingthread forever.  If the mutex is of the ``error checking'' kind,@code{pthread_mutex_lock} returns immediately with the error code@code{EDEADLK}.  If the mutex is of the ``recursive'' kind, 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 kind is ``fast'', that is, @code{PTHREAD_MUTEX_FAST_NP}.@comment pthread.h@comment GNU@deftypefun int pthread_mutexattr_setkind_np (pthread_mutexattr_t *@var{attr}, int @var{kind})@code{pthread_mutexattr_setkind_np} sets the mutex kind attribute in@var{attr} to the value specified by @var{kind}.If @var{kind} is not @code{PTHREAD_MUTEX_FAST_NP},@code{PTHREAD_MUTEX_RECURSIVE_NP}, or@code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return@code{EINVAL} and leave @var{attr} unchanged.@end deftypefun@comment pthread.h@comment GNU@deftypefun int pthread_mutexattr_getkind_np (const pthread_mutexattr_t *@var{attr}, int *@var{kind})@code{pthread_mutexattr_getkind_np} retrieves the current value of themutex kind attribute in @var{attr} and stores it in the location pointedto by @var{kind}.This function always returns 0.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -