📄 linuxthreads.texi
字号:
@code{pthread_key_create} returns 0 unless @code{PTHREAD_KEYS_MAX} keyshave 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 checkwhether non-@code{NULL} values are associated with that key in thecurrently executing threads, nor call the destructor function associatedwith the key.If there is no such key @var{key}, it returns @code{EINVAL}. Otherwiseit 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}. Otherwiseit 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 deftypefunThe following code fragment allocates a thread-specific array of 100characters, 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 asdescribed by the @var{how} and @var{newmask} arguments. If @var{oldmask}is not @code{NULL}, the previous signal mask is stored in the locationpointed to by @var{oldmask}.The meaning of the @var{how} and @var{newmask} arguments is the same asfor @code{sigprocmask}. If @var{how} is @code{SIG_SETMASK}, the signalmask 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 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 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.@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. To avoid this, install handlers with@code{pthread_atfork} as follows: the @var{prepare} handler locks theglobal mutexes (in locking order), and the @var{parent} and @var{child}handlers unlock them (in reverse order). Alternatively, @var{prepare}and @var{parent} can be set to @code{NULL} and @var{child} to a functionthat calls @code{pthread_mutex_init} on the global mutexes.@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.@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 thethread @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} specifiesthe 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 returnsone 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 notvalid for the specified policy@item EPERMRealtime scheduling was requested but the calling process does not havesufficient privileges.@item ESRCHThe @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 andscheduling parameters for the thread @var{target_thread} and stores themin the locations pointed to by @var{policy} and @var{param},respectively.@code{pthread_getschedparam} returns 0 on success, or one of thefollowing error codes on failure:@table @code@item ESRCHThe @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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -