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

📄 linuxthreads.texi

📁 用于嵌入式Linux系统的标准C的库函数
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
mask is set to @var{newmask}. If @var{how} is @code{SIG_BLOCK}, thesignals 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 signalactions and signal handlers, as set with @code{sigaction}, are sharedbetween all threads.The @code{pthread_sigmask} function returns 0 on success, and one of thefollowing 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 codeson error:@table @code@item EINVAL@var{signo} is not a valid signal number@item ESRCHThe 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 numberof the signal received in the location pointed to by @var{sig} andreturns. The signals in @var{set} must be blocked and not ignored onentrance to @code{sigwait}. If the delivered signal has a signal handlerfunction attached, that function is @emph{not} called.@code{sigwait} is a cancellation point.  It always returns 0.@end deftypefunFor @code{sigwait} to work reliably, the signals being waited for must beblocked in all threads, not only in the calling thread, sinceotherwise the POSIX semantics for signal delivery do not guaranteethat 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 threadsare created, and never unblock them in the program other than bycalling @code{sigwait}.Signal handling in LinuxThreads departs significantly from the POSIXstandard. According to the standard, ``asynchronous'' (external) signalsare addressed to the whole process (the collection of all threads),which then delivers them to one particular thread. The thread thatactually receives the signal is any thread that does not currently blockthe signal.In LinuxThreads, each thread is actually a kernel process with its ownPID, so external signals are always directed to one particular thread.If, for instance, another thread is blocked in @code{sigwait} on thatsignal, it will not be restarted.The LinuxThreads implementation of @code{sigwait} installs dummy signalhandlers for the signals in @var{set} for the duration of thewait. Since signal handlers are shared between all threads, otherthreads must not attach their own signal handlers to these signals, oralternatively they should all block these signals (which is recommendedanyway).@node Threads and Fork@section Threads and ForkIt's not intuitively obvious what should happen when a multi-threaded POSIXprocess calls @code{fork}. Not only are the semantics tricky, but you mayneed to write code that does the right thing at fork time even if that codedoesn't use the @code{fork} function. Moreover, you need to be aware ofinteraction 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 newprocess which is copy of the  calling process. Effectively, in addition tocopying certain system objects, the function takes a snapshot of the memoryareas of the parent process, and creates identical areas in the child.To make matters more complicated, with threads it's possible for two or morethreads 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 doesnot inherit any of its threads. Execution of the child process is carried outby a new thread which returns from @code{fork} function with a return value ofzero; it is the only thread in the child process.  Because threads are notinherited 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 havebeen executing critical regions of code.  As a result, the child process mayget a copy of objects that are not in a well-defined state.  This potentialproblem affects all components of the program.Any program component which will continue being used in a child process mustcorrectly handle its state during @code{fork}. For this purpose, the POSIXinterface provides the special function @code{pthread_atfork} for installingpointers 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 justbefore and just after a new process is created with @code{fork}. The@var{prepare} handler will be called from the parent process, justbefore the new process is created. The @var{parent} handler will becalled 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 onerror.One or more of the three handlers @var{prepare}, @var{parent} and@var{child} can be given as @code{NULL}, meaning that no handler needsto be called at the corresponding point.@code{pthread_atfork} can be called several times to install severalsets of handlers. At @code{fork} time, the @var{prepare} handlers arecalled in LIFO order (last added with @code{pthread_atfork}, firstcalled 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 itreturns 0.The functions @code{fork} and @code{pthread_atfork} must not be regarded asreentrant 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, eitherall three handlers will be called, or none of them will be called.The handlers are inherited by the child process, and there is noway to remove them, short of using @code{exec} to load a newpocess image.@end deftypefunTo understand the purpose of @code{pthread_atfork}, recall that@code{fork} duplicates the whole memory space, including mutexes intheir current locking state, but only the calling thread: other threadsare not running in the child process. Thus, if a mutex is locked by athread other than the thread calling @code{fork}, that mutex will remainlocked forever in the child process, possibly blocking the execution ofthe child process. Or if some shared data, such as a linked list, was in themiddle of being updated by a thread in the parent process, the childwill get a copy of the incompletely updated data which it cannot use.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 resetthe mutexes using @code{pthread_mutex_init}, as well as any othersynchronization objects such as condition variables.Locking the global mutexes before the fork ensures that all other threads arelocked out of the critical regions of code protected by those mutexes.  Thuswhen @code{fork} takes a snapshot of the parent's address space, that snapshotwill copy valid, stable data.  Resetting the synchronization objects in thechild process will ensure they are properly cleansed of any artifacts from thethreading subsystem of the parent process. For example, a mutex may inherita wait queue of threads waiting for the lock; this wait queue makes no sensein the child process. Initializing the mutex takes care of this.@node Streams and Fork@section Streams and ForkThe GNU standard I/O library has an internal mutex which guards the internallinked list of all standard C FILE objects. This mutex is properly taken careof 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 insertinto the list.However, the individual stream locks are not completely taken care of.  Thusunless the multithreaded application takes special precautions in its use of@code{fork}, the child process might not be able to safely use the streams thatit inherited from the parent.   In general, for any given open stream in theparent that is to be used by the child process, the application must ensurethat 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 toensure this is to use @code{flockfile} to lock the stream prior to calling@code{fork} and then unlock it with @code{funlockfile} inside the parentprocess, provided that the parent's threads properly honor these locks.Nothing special needs to be done in the child process, since the libraryinternally 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 properlytreated and can be safely used in the child, the stream locks do not providean exclusion mechanism between the parent and child. If both processes writeto @code{stdout}, strangely interleaved output may result regardless ofthe explicit use of @code{flockfile} or implicit locks.Also note that these provisions are a GNU extension; other systems might notprovide 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 onlyasynchronous safe functions, which excludes much of the library, includingstandard 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 samethread.A non-zero value is returned if @var{thread1} and @var{thread2} refer tothe 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 detachedstate. This guarantees that the memory resources consumed by @var{th}will be freed immediately when @var{th} terminates. However, thisprevents 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 alreadyjoining the thread @var{th} at the time @code{pthread_detach} is called,@code{pthread_detach} does nothing and leaves @var{th} in the joinablestate.On success, 0 is returned. On error, one of the following codes isreturned:@table @code@item ESRCHNo thread could be found corresponding to that specified by @var{th}@item EINVALThe 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, exceptthe calling thread which proceeds normally. It is intended to becalled 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 cancellationmechanism. Hence, the current settings for cancellation state andcancellation type are ignored, and the cleanup handlers are notexecuted in the terminated threads.According to POSIX 1003.1c, a successful @code{exec*} in one of thethreads 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 muchof the same behavior, except that if @code{exec*} ultimately fails, thenall 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 ofinitialization code is executed at most once. The @var{once_control}argument points to a static or extern variable statically initializedto @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 noargument and changes the value of the @var{once_control} variable torecord that initialization has been performed. Subsequent calls to@code{pthread_once} with the same @code{once_control} argument donothing.If a thread is cancelled while executing @var{init_routine}the state of the @var{once_control} variable is reset so thata 

⌨️ 快捷键说明

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