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

📄 linuxthreads.texi

📁 用于嵌入式Linux系统的标准C的库函数
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
pthread_mutex_unlock(&mut);@end smallexampleModifications on @var{x} and @var{y} that may cause @var{x} to become greater than@var{y} should signal the condition if needed:@smallexamplepthread_mutex_lock(&mut);/* modify x and y */if (x > y) pthread_cond_broadcast(&cond);pthread_mutex_unlock(&mut);@end smallexampleIf it can be proved that at most one waiting thread needs to be wakenup (for instance, if there are only two threads communicating through@var{x} and @var{y}), @code{pthread_cond_signal} can be used as a slightly moreefficient alternative to @code{pthread_cond_broadcast}. In doubt, use@code{pthread_cond_broadcast}.To wait for @var{x} to becomes greater than @var{y} with a timeout of 5seconds, do:@smallexamplestruct timeval now;struct timespec timeout;int retcode;pthread_mutex_lock(&mut);gettimeofday(&now);timeout.tv_sec = now.tv_sec + 5;timeout.tv_nsec = now.tv_usec * 1000;retcode = 0;while (x <= y && retcode != ETIMEDOUT) @{        retcode = pthread_cond_timedwait(&cond, &mut, &timeout);@}if (retcode == ETIMEDOUT) @{        /* timeout occurred */@} else @{        /* operate on x and y */@}pthread_mutex_unlock(&mut);@end smallexampleCondition attributes can be specified at condition creation time, bypassing a condition attribute object as second argument to@code{pthread_cond_init}.  Passing @code{NULL} is equivalent to passinga condition attribute object with all attributes set to their defaultvalues.The LinuxThreads implementation supports no attributes forconditions. The functions on condition attributes are included only forcompliance with the POSIX standard.@comment pthread.h@comment POSIX@deftypefun int pthread_condattr_init (pthread_condattr_t *@var{attr})@deftypefunx int pthread_condattr_destroy (pthread_condattr_t *@var{attr})@code{pthread_condattr_init} initializes the condition attribute object@var{attr} and fills it with default values for the attributes.@code{pthread_condattr_destroy} destroys the condition attribute object@var{attr}.Both functions do nothing in the LinuxThreads implementation.@code{pthread_condattr_init} and @code{pthread_condattr_destroy} alwaysreturn 0.@end deftypefun@node POSIX Semaphores@section POSIX Semaphores@vindex SEM_VALUE_MAXSemaphores are counters for resources shared between threads. Thebasic operations on semaphores are: increment the counter atomically,and wait until the counter is non-null and decrement it atomically.Semaphores have a maximum value past which they cannot be incremented.The macro @code{SEM_VALUE_MAX} is defined to be this maximum value.  Inthe GNU C library, @code{SEM_VALUE_MAX} is equal to @code{INT_MAX}(@pxref{Range of Type}), but it may be much smaller on other systems.The pthreads library implements POSIX 1003.1b semaphores.  These shouldnot be confused with System V semaphores (@code{ipc}, @code{semctl} and@code{semop}).@c !!! SysV IPC is not doc'd at all in our manualAll the semaphore functions and macros are defined in @file{semaphore.h}.@comment semaphore.h@comment POSIX@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value})@code{sem_init} initializes the semaphore object pointed to by@var{sem}. The count associated with the semaphore is set initially to@var{value}. The @var{pshared} argument indicates whether the semaphoreis local to the current process (@var{pshared} is zero) or is to beshared between several processes (@var{pshared} is not zero).On success @code{sem_init} returns 0.  On failure it returns -1 and sets@var{errno} to one of the following values:@table @code@item EINVAL@var{value} exceeds the maximal counter value @code{SEM_VALUE_MAX}@item ENOSYS@var{pshared} is not zero.  LinuxThreads currently does not supportprocess-shared semaphores.  (This will eventually change.)@end table@end deftypefun@comment semaphore.h@comment POSIX@deftypefun int sem_destroy (sem_t * @var{sem})@code{sem_destroy} destroys a semaphore object, freeing the resources itmight hold.  If any threads are waiting on the semaphore when@code{sem_destroy} is called, it fails and sets @var{errno} to@code{EBUSY}.In the LinuxThreads implementation, no resources are associated withsemaphore objects, thus @code{sem_destroy} actually does nothing exceptchecking that no thread is waiting on the semaphore.  This will changewhen process-shared semaphores are implemented.@end deftypefun@comment semaphore.h@comment POSIX@deftypefun int sem_wait (sem_t * @var{sem})@code{sem_wait} suspends the calling thread until the semaphore pointedto by @var{sem} has non-zero count. It then atomically decreases thesemaphore count.@code{sem_wait} is a cancellation point.  It always returns 0.@end deftypefun@comment semaphore.h@comment POSIX@deftypefun int sem_trywait (sem_t * @var{sem})@code{sem_trywait} is a non-blocking variant of @code{sem_wait}. If thesemaphore pointed to by @var{sem} has non-zero count, the count isatomically decreased and @code{sem_trywait} immediately returns 0.  Ifthe semaphore count is zero, @code{sem_trywait} immediately returns -1and sets errno to @code{EAGAIN}.@end deftypefun@comment semaphore.h@comment POSIX@deftypefun int sem_post (sem_t * @var{sem})@code{sem_post} atomically increases the count of the semaphore pointed toby @var{sem}. This function never blocks.@c !!! This para appears not to agree with the code.On processors supporting atomic compare-and-swap (Intel 486, Pentium andlater, Alpha, PowerPC, MIPS II, Motorola 68k, Ultrasparc), the@code{sem_post} function is can safely be called from signal handlers.This is the only thread synchronization function provided by POSIXthreads that is async-signal safe.  On the Intel 386 and earlier Sparcchips, the current LinuxThreads implementation of @code{sem_post} is notasync-signal safe, because the hardware does not support the requiredatomic operations.@code{sem_post} always succeeds and returns 0, unless the semaphorecount would exceed @code{SEM_VALUE_MAX} after being incremented.  Inthat case @code{sem_post} returns -1 and sets @var{errno} to@code{EINVAL}.  The semaphore count is left unchanged.@end deftypefun@comment semaphore.h@comment POSIX@deftypefun int sem_getvalue (sem_t * @var{sem}, int * @var{sval})@code{sem_getvalue} stores in the location pointed to by @var{sval} thecurrent count of the semaphore @var{sem}.  It always returns 0.@end deftypefun@node Thread-Specific Data@section Thread-Specific DataPrograms often need global or static variables that have differentvalues in different threads. Since threads share one memory space, thiscannot be achieved with regular variables. Thread-specific data is thePOSIX threads answer to this need.Each thread possesses a private memory block, the thread-specific dataarea, or TSD area for short. This area is indexed by TSD keys. The TSDarea associates values of type @code{void *} to TSD keys. TSD keys arecommon to all threads, but the value associated with a given TSD key canbe different in each thread.For concreteness, the TSD areas can be viewed as arrays of @code{void *}pointers, TSD keys as integer indices into these arrays, and the valueof a TSD key as the value of the corresponding array element in thecalling thread.When a thread is created, its TSD area initially associates @code{NULL}with all keys.@comment pthread.h@comment POSIX@deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*destr_function) (void *))@code{pthread_key_create} allocates a new TSD key. The key is stored inthe location pointed to by @var{key}. There is a limit of@code{PTHREAD_KEYS_MAX} on the number of keys allocated at a giventime. The value initially associated with the returned key is@code{NULL} in all currently executing threads.The @var{destr_function} argument, if not @code{NULL}, specifies adestructor function associated with the key. When a thread terminatesvia @code{pthread_exit} or by cancellation, @var{destr_function} iscalled on the value associated with the key in that thread. The@var{destr_function} is not called if a key is deleted with@code{pthread_key_delete} or a value is changed with@code{pthread_setspecific}.  The order in which destructor functions arecalled at thread termination time is unspecified.Before the destructor function is called, the @code{NULL} value isassociated with the key in the current thread.  A destructor functionmight, however, re-associate non-@code{NULL} values to that key or someother key.  To deal with this, if after all the destructors have beencalled for all non-@code{NULL} values, there are still somenon-@code{NULL} values with associated destructors, then the process isrepeated.  The LinuxThreads implementation stops the process after@code{PTHREAD_DESTRUCTOR_ITERATIONS} iterations, even if somenon-@code{NULL} values with associated descriptors remain.  Otherimplementations may loop indefinitely.@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 signal

⌨️ 快捷键说明

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