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

📄 linuxthreads.texi

📁 Newlib 嵌入式 C库 标准实现代码
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
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 guardsizeChange the minimum size in bytes of the guard area for the thread'sstack.  The default size is a single page.  If this value is set, itwill 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 allocatedfor the guard area is used to catch stack overflow.  Therefore, whenallocating large structures on the stack, a larger guard area may berequired 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 CancellationCancellation is the mechanism by which a thread can terminate theexecution of another thread. More precisely, a thread can send acancellation request to another thread. Depending on its settings, thetarget thread can then either ignore the request, honor it immediately,or defer it till it reaches a cancellation point.  When threads arefirst created by @code{pthread_create}, they always defer cancellationrequests.When a thread eventually honors a cancellation request, it behaves as if@code{pthread_exit(PTHREAD_CANCELED)} was called.  All cleanup handlersare executed in reverse order, finalization functions forthread-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 pendingcancellation 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.  Inaddition, 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@noindentAll 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 thecalling thread -- that is, whether cancellation requests are ignored ornot. 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 (cancellationrequests are ignored).If @var{oldstate} is not @code{NULL}, the previous cancellation state isstored in the location pointed to by @var{oldstate}, and can thus berestored 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 andreturns @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 tocancellation 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 threadas soon as the cancellation request is received, or@code{PTHREAD_CANCEL_DEFERRED} to keep the cancellation request pendinguntil 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} failsand 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 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 canceled 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 type}, which is either ``fast'', ``recursive'', or``error checking''. The type of a mutex determines whetherit 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 initializedstatically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (fortimed mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (forrecursive 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 iscurrently unlocked, it becomes locked and owned by the calling thread,and @code{pthread_mutex_lock} returns immediately. If the mutex is

⌨️ 快捷键说明

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