Skip Navigation Links | |
Exit Print View | |
Multithreaded Programming Guide Oracle Solaris 11.1 Information Library |
1. Covering Multithreading Basics
4. Programming with Synchronization Objects
Mutual Exclusion Lock Attributes
Initializing a Mutex Attribute Object
pthread_mutexattr_init Return Values
Destroying a Mutex Attribute Object
pthread_mutexattr_destroy Syntax
pthread_mutexattr_destroy Return Values
pthread_mutexattr_setpshared Syntax
pthread_mutexattr_setpshared Return Values
pthread_mutexattr_getpshared Syntax
pthread_mutexattr_getpshared Return Values
Setting the Mutex Type Attribute
pthread_mutexattr_settype Syntax
pthread_mutexattr_settype Return Values
Getting the Mutex Type Attribute
pthread_mutexattr_gettype Syntax
pthread_mutexattr_gettype Return Values
Setting the Mutex Attribute's Protocol
pthread_mutexattr_setprotocol Syntax
pthread_mutexattr_setprotocol Return Values
Getting the Mutex Attribute's Protocol
pthread_mutexattr_getprotocol Syntax
pthread_mutexattr_getprotocol Return Values
Setting the Mutex Attribute's Priority Ceiling
pthread_mutexattr_setprioceiling Syntax
pthread_mutexattr_setprioceiling Return Values
Getting the Mutex Attribute's Priority Ceiling
pthread_mutexattr_getprioceiling Syntax
pthread_mutexattr_getprioceiling Return Values
Setting the Mutex's Priority Ceiling
pthread_mutex_setprioceiling Syntax
pthread_mutex_setprioceiling Return Values
Getting the Mutex's Priority Ceiling
pthread_mutex_getprioceiling Syntax
pthread_mutex_getprioceiling Return Values
Setting the Mutex's Robust Attribute
pthread_mutexattr_setrobust_np Syntax
pthread_mutexattr_setrobust_np Return Values
Getting the Mutex's Robust Attribute
pthread_mutex_init Return Values
pthread_mutex_consistent_np Syntax
pthread_mutex_consistent_np Return Values
pthread_mutex_lock Return Values
pthread_mutex_unlock Return Values
Locking a Mutex Without Blocking
pthread_mutex_trylock Return Values
Locking a Mutex Before a Specified Absolute Time
pthread_mutex_timedlock() Syntax
pthread_mutex_timedlock() Return Values
Locking a Mutex Within a Specified Time Interval
pthread_mutex_reltimedlock_np() Syntax
pthread_mutex_reltimedlock_np() Return Values
pthread_mutex_destroy Return Values
Code Examples of Mutex Locking
Examples of Using Lock Hierarchies
Examples of Using Nested Locking With a Singly-Linked List
Example of Nested Locking With a Circularly-Linked List
pthread_spin_init() Return Values
pthread_spin_lock() Return Values
Acquiring a Non-Blocking Spin Lock
pthread_spin_trylock() Return Values
pthread_spin_unlock() Return Values
pthread_spin_destroy() Return Values
Initializing a Condition Variable Attribute
pthread_condattr_init Return Values
Removing a Condition Variable Attribute
pthread_condattr_destroy Syntax
pthread_condattr_destroy Return Values
Setting the Scope of a Condition Variable
pthread_condattr_setpshared Syntax
pthread_condattr_setpshared Return Values
Getting the Scope of a Condition Variable
pthread_condattr_getpshared Syntax
pthread_condattr_getpshared Return Values
Setting the Clock Selection Condition Variable
pthread_condattr_setclock Syntax
pthread_condattr_setclock Returns
Getting the Clock Selection Condition Variable
pthread_condattr_getclock Syntax
pthread_condattr_getclock Returns
Initializing a Condition Variable
pthread_cond_init Return Values
Blocking on a Condition Variable
pthread_cond_wait Return Values
pthread_cond_signal Return Values
Blocking Until a Specified Time
pthread_cond_timedwait Return Values
Blocking For a Specified Interval
pthread_cond_reltimedwait_np Syntax
pthread_cond_reltimedwait_np Return Values
pthread_cond_broadcast Return Values
Destroying the Condition Variable State
pthread_cond_destroy Return Values
Synchronization With Semaphores
Initializing Semaphores With Intraprocess Scope
Initializing Semaphores With Interprocess Scope
Decrementing a Semaphore Count
Destroying the Semaphore State
Producer and Consumer Problem Using Semaphores
Initializing a Read-Write Lock Attribute
pthread_rwlockattr_init Syntax
pthread_rwlockattr_init Return Values
Destroying a Read-Write Lock Attribute
pthread_rwlockattr_destroy Syntax
pthread_rwlockattr_destroy Return Values
Setting a Read-Write Lock Attribute
pthread_rwlockattr_setpshared Syntax
pthread_rwlockattr_setpshared Return Values
Getting a Read-Write Lock Attribute
pthread_rwlockattr_getpshared Syntax
pthread_rwlockattr_getpshared Return Values
Initializing a Read-Write Lock
pthread_rwlock_init Return Values
Acquiring the Read Lock on Read-Write Lock
pthread_rwlock_rdlock Return Values
Acquiring a Read Lock on a Read-Write Lock Before a Specified Absolute Time
pthread_rwlock_timedrdlock Syntax
pthread_rwlock_timedrdlock Return Values
Acquiring a Non-Blocking Read Lock on a Read-Write Lock
pthread_rwlock_tryrdlock Syntax
pthread_rwlock_tryrdlock Return Values
Acquiring the Write Lock on a Read-Write Lock
pthread_rwlock_wrlock Return Values
Acquiring a Non-blocking Write Lock on a Read-Write Lock
pthread_rwlock_trywrlock Syntax
pthread_rwlock_trywrlock Return Values
Acquiring a Write Lock on a Read-Write Lock Before a Specified Absolute Time
pthread_rwlock_timedwrlock Syntax
pthread_rwlock_timedwrlock Returns
pthread_rwlock_unlock Return Values
pthread_rwlock_destroy Return Values
Initializing a Synchronization Barrier
pthread_barrier_init() Return Values
Waiting for Threads to Synchronize at a Barrier
pthread_barrier_wait() Return Values
Destroying a Synchronization Barrier
pthread_barrier_destroy Syntax
pthread_barrier_destroy Return Values
Initializing a Barrier Attributes Object
pthread_barrierattr_init() Syntax
pthread_barrierattr_init() Return Values
Setting a Barrier Process-Shared Attribute
pthread_barrierattr_setpshared() Syntax
pthread_barrierattr_setpshared() Return Values
Getting a Barrier Process-Shared Attribute
pthread_barrierattr_getpshared() Syntax
pthread_barrierattr_getpshared() Return Values
Destroying a Barrier Attributes Object
pthread_barrierattr_destroy() Syntax
pthread_barrierattr_destroy() Return Values
Synchronization Across Process Boundaries
Producer and Consumer Problem Example
5. Programming With the Oracle Solaris Software
6. Programming With Oracle Solaris Threads
Use mutual exclusion locks (mutexes) to serialize thread execution. Mutual exclusion locks synchronize threads, usually by ensuring that only one thread at a time executes a critical section of code. Mutex locks can also preserve single-threaded code.
To change the default mutex attributes, you can declare and initialize an attribute object. Often, the mutex attributes are set in one place at the beginning of the application so the attributes can be located quickly and modified easily. Table 4-1 lists the functions that manipulate mutex attributes.
Table 4-1 Mutex Attributes Routines
|
Use pthread_mutexattr_init(3C) to initialize attributes that are associated with the mutex object to their default values. Storage for each attribute object is allocated by the threads system during execution.
int pthread_mutexattr_init(pthread_mutexattr_t *mattr);
#include <pthread.h> pthread_mutexattr_t mattr; int ret; /* initialize an attribute to default value */ ret = pthread_mutexattr_init(&mattr);
mattr is an opaque type that contains a system-allocated attribute object. See Table 4-2 for information about the attributes in the mattr object.
Before a mutex attribute object can be reinitialized, the object must first be destroyed by a call to pthread_mutexattr_destroy(3C). The pthread_mutexattr_init() call results in the allocation of an opaque object. If the object is not destroyed, a memory leak results.
Table 4-2 Default Attribute Values for mattr
|
pthread_mutexattr_init() returns zero after completing successfully. Any other return value indicates that an error occurred. If either of the following conditions occurs, the function fails and returns the corresponding value.
ENOMEM
Description: Insufficient memory exists to initialize the mutex attribute object.
pthread_mutexattr_destroy(3C) deallocates the storage space used to maintain the attribute object created by pthread_mutexattr_init().
int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr)
#include <pthread.h> pthread_mutexattr_t mattr; int ret; /* destroy an attribute */ ret = pthread_mutexattr_destroy(&mattr);
pthread_mutexattr_destroy() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.
EINVAL
Description: The value specified by mattr is invalid.
pthread_mutexattr_setpshared(3C) sets the scope of the mutex variable.
int pthread_mutexattr_setpshared(pthread_mutexattr_t *restrict mattr, int *restrict pshared);
#include <pthread.h> pthread_mutexattr_t mattr; int ret; ret = pthread_mutexattr_init(&mattr); /* * resetting to its default value: private */ ret = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE);
The scope of a mutex variable can be either process private (intraprocess) or system wide (interprocess). To share the mutex among threads from more than one process, create the mutex in shared memory with the pshared attribute set to PTHREAD_PROCESS_SHARED .
If the mutex pshared attribute is set to PTHREAD_PROCESS_PRIVATE , only those threads created by the same process can operate on the mutex.
pthread_mutexattr_setpshared() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.
EINVAL
Description: The value specified by mattr is invalid.
pthread_mutexattr_getpshared(3C) returns the scope of the mutex variable defined by pthread_mutexattr_setpshared().
int pthread_mutexattr_getpshared(pthread_mutexattr_t *restrict mattr, int *restrict pshared);
#include <pthread.h> pthread_mutexattr_t mattr; int pshared, ret; /* get pshared of mutex */ ret = pthread_mutexattr_getpshared(&mattr, &pshared);
Get the current value of pshared for the attribute object mattr. The value is either PTHREAD_PROCESS_SHARED or PTHREAD_PROCESS_PRIVATE.
pthread_mutexattr_getpshared() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.
EINVAL
Description: The value specified by mattr is invalid.
pthread_mutexattr_settype(3C) sets the mutex type attribute.
#include <pthread.h> int pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type);
The default value of the type attribute is PTHREAD_MUTEX_DEFAULT.
The type argument specifies the type of mutex. The following list describes the valid mutex types:
PTHREAD_MUTEX_NORMAL
Description: This type of mutex does not detect deadlock. A thread attempting to relock this mutex without first unlocking the mutex deadlocks. Attempting to unlock a mutex locked by a different thread results in undefined behavior. Attempting to unlock an unlocked mutex results in undefined behavior.
PTHREAD_MUTEX_ERRORCHECK
Description: This type of mutex provides error checking. A thread attempting to relock this mutex without first unlocking the mutex returns an error. A thread attempting to unlock a mutex that another thread has locked returns an error. A thread attempting to unlock an unlocked mutex returns an error.
PTHREAD_MUTEX_RECURSIVE
Description: A thread attempting to relock this mutex without first unlocking the mutex succeeds in locking the mutex. The relocking deadlock that can occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. Multiple locks of this mutex require the same number of unlocks to release the mutex before another thread can acquire the mutex. A thread attempting to unlock a mutex that another thread has locked returns an error. A thread attempting to unlock an unlocked mutex returns an error.
PTHREAD_MUTEX_DEFAULT
Description: An implementation is allowed to map this attribute to one of the other mutex types. The Oracle Solaris implementation maps this attribute to PTHREAD_PROCESS_NORMAL.
If successful, the pthread_mutexattr_settype function returns zero. Otherwise, an error number is returned to indicate the error.
EINVAL
Description: The value type or attr is invalid.
pthread_mutexattr_gettype(3C) gets the mutex type attribute set by pthread_mutexattr_settype().
#include <pthread.h> int pthread_mutexattr_gettype(pthread_mutexattr_t *restrict attr , int *restrict type);
The default value of the type attribute is PTHREAD_MUTEX_DEFAULT.
The type argument specifies the type of mutex. Valid mutex types include
PTHREAD_MUTEX_NORMAL
PTHREAD_MUTEX_ERRORCHECK
PTHREAD_MUTEX_RECURSIVE
PTHREAD_MUTEX_DEFAULT
For a description of each type, see pthread_mutexattr_settype Syntax.
On successful completion, pthread_mutexattr_gettype() returns 0. Any other return value indicates that an error occurred.
EINVAL
Description: The value specified by type is invalid.
pthread_mutexattr_setprotocol(3C) sets the protocol attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
attr points to a mutex attribute object created by an earlier call to pthread_mutexattr_init().
protocol defines the protocol that is applied to the mutex attribute object.
The value of protocol that is defined in pthread.h can be one of the following values: PTHREAD_PRIO_NONE , PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT .
PTHREAD_PRIO_NONE
A thread's priority and scheduling are not affected by the mutex ownership.
PTHREAD_PRIO_INHERIT
This protocol value affects an owning thread's priority and scheduling. When higher-priority threads block on one or more mutexes owned by thrd1 where those mutexes are initialized with PTHREAD_PRIO_INHERIT, thrd1 runs with the higher of its priority or the highest priority of any thread waiting on any of the mutexes owned by thrd1.
If thrd1 blocks on a mutex owned by another thread, thrd3, the same priority inheritance effect recursively propagates to thrd3.
Use PTHREAD_PRIO_INHERIT to avoid priority inversion. Priority inversion occurs when a low-priority thread holds a lock that a higher-priority thread requires. The higher-priority thread cannot continue until the lower-priority thread releases the lock.
Without priority inheritance, the lower priority thread might not be scheduled to run for a long time, causing the higher priority thread to block equally long. Priority inheritance temporarily raises the priority of the lower priority thread so it will be scheduled to run quickly and release the lock, allowing the higher priority thread to acquire it. The lower-priority thread reverts to its lower priority when it releases the lock.
PTHREAD_PRIO_PROTECT
This protocol value affects the priority and scheduling of a thread, such as thrd2, when the thread owns one or more mutexes that are initialized with PTHREAD_PRIO_PROTECT. thrd2 runs with the higher of its priority or the highest-priority ceiling of all mutexes owned by thrd2. Higher-priority threads blocked on any of the mutexes, owned by thrd2, have no effect on the scheduling of thrd2.
The PTHREAD_PRIO_INHERIT and PTHREAD_PRIO_PROTECT mutex attributes are usable only by privileged processes running in the realtime (RT) scheduling class SCHED_FIFO or SCHED_RR.
A thread can simultaneously own several mutexes initialized with a mix of PTHREAD_PRIO_INHERIT and PTHREAD_PRIO_PROTECT. In this case, the thread executes at the highest priority obtained by either of these protocols.
On successful completion, pthread_mutexattr_setprotocol() returns 0. Any other return value indicates that an error occurred.
If either of the following conditions occurs, pthread_mutexattr_setprotocol() might fail and return the corresponding value.
EINVAL
Description: The value specified by attr or protocol is not valid.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_getprotocol(3C) gets the protocol attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict attr, int *restrict protocol);
attr points to a mutex attribute object created by an earlier call to pthread_mutexattr_init().
protocol contains one of the following protocol attributes: PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT which are defined by the header <pthread.h>.
On successful completion, pthread_mutexattr_getprotocol() returns 0. Any other return value indicates that an error occurred.
If either of the following conditions occurs, pthread_mutexattr_getprotocol() might fail and return the corresponding value.
EINVAL
Description: The value specified by attr is NULL, or the value specified by attr or protocol is invalid.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_setprioceiling(3C) sets the priority ceiling attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_setprioceiling(pthread_mutexatt_t *attr, int prioceiling);
attr points to a mutex attribute object created by an earlier call to pthread_mutexattr_init().
prioceiling specifies the priority ceiling of initialized mutexes. The ceiling defines the minimum priority level at which the critical section guarded by the mutex is executed. prioceiling falls within the maximum range of priorities defined by SCHED_FIFO. To avoid priority inversion, set prioceiling to a priority higher than or equal to the highest priority of all threads that might lock the particular mutex.
On successful completion, pthread_mutexattr_setprioceiling() returns 0. Any other return value indicates that an error occurred.
If either of the following conditions occurs, pthread_mutexattr_setprioceiling() might fail and return the corresponding value.
EINVAL
Description: The value specified by attr is NULL or invalid or prioceiling is invalid.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_getprioceiling(3C) gets the priority ceiling attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_getprioceiling(const pthread_mutexatt_t *restrict attr, int *restrict prioceiling);
attr designates the attribute object created by an earlier call to pthread_mutexattr_init().
pthread_mutexattr_getprioceiling() returns the priority ceiling of initialized mutexes in prioceiling. The ceiling defines the minimum priority level at which the critical section guarded by the mutex is executed. prioceiling falls within the maximum range of priorities defined by SCHED_FIFO. To avoid priority inversion, set prioceiling to a priority higher than or equal to the highest priority of all threads that might lock the particular mutex.
On successful completion, pthread_mutexattr_getprioceiling() returns 0. Any other return value indicates that an error occurred.
If either of the following conditions occurs, pthread_mutexattr_getprioceiling() might fail and return the corresponding value.
EINVAL
Description: The value specified by attr is NULL.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_setprioceiling(3C) sets the priority ceiling of a mutex.
#include <pthread.h> int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, int prioceiling, int *restrict old_ceiling);
pthread_mutex_setprioceiling() changes the priority ceiling, prioceiling, of a mutex, mutex. pthread_mutex_setprioceiling() locks a mutex if unlocked, or blocks until pthread_mutex_setprioceiling() successfully locks the mutex, changes the priority ceiling of the mutex and releases the mutex. The process of locking the mutex need not adhere to the priority protect protocol.
If pthread_mutex_setprioceiling() succeeds, the previous value of the priority ceiling is returned in old_ceiling. If pthread_mutex_setprioceiling() fails, the mutex priority ceiling remains unchanged.
On successful completion, pthread_mutex_setprioceiling() returns 0. Any other return value indicates that an error occurred.
If any of the following conditions occurs, pthread_mutex_setprioceiling() might fail and return the corresponding value.
EINVAL
Description: The priority requested by prioceiling is out of range.
EINVAL
Description: The mutex was not initialized with its protocol attribute having the value of THREAD_PRIO_PROTECT.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_getprioceiling(3C) gets the priority ceiling of a mutex.
#include <pthread.h> int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, int *restrict prioceiling);
pthread_mutex_getprioceiling() returns the priority ceiling, prioceiling of a mutex.
On successful completion, pthread_mutex_getprioceiling() returns 0. Any other return value indicates that an error occurred.
If any of the following conditions occurs, pthread_mutexatt_getprioceiling() fails and returns the corresponding value.
If any of the following conditions occurs, pthread_mutex_getprioceiling() might fail and return the corresponding value.
EINVAL
Description: The value specified by mutex does not refer to a currently existing mutex.
EPERM
Description: The caller does not have the privilege to perform the operation.
pthread_mutexattr_setrobust_np sets the robust attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_setrobust_np(pthread_mutexattr_t *attr, int *robustness);
Note - pthread_mutexattr_setrobust_np() applies only if the symbol _POSIX_THREAD_PRIO_INHERIT is defined.
In the Oracle Solaris 10 and prior releases, the PTHREAD_MUTEX_ROBUST_NP attribute can only be applied to mutexes that are also marked with the PTHREAD_PRIO_INHERIT protocol attribute. This restriction is lifted in subsequent Oracle Solaris releases.
attr points to the mutex attribute object previously created by a call to pthread_mutexattr_init().
robustness defines the behavior when the owner of the mutex terminates without unlocking the mutex, usually because its process terminated abnormally. The value of robustness that is defined in pthread.h is PTHREAD_MUTEX_ROBUST_NP or PTHREAD_MUTEX_STALLED_NP. The default value is PTHREAD_MUTEX_STALLED_NP .
PTHREAD_MUTEX_STALLED_NP
When the owner of the mutex terminates without unlocking the mutex, all subsequent calls to pthread_mutex_lock() are blocked from progress in an unspecified manner.
PTHREAD_MUTEX_ROBUST_NP
When the owner of the mutex terminates without unlocking the mutex, the mutex is unlocked. The next owner of this mutex acquires the mutex with an error return of EOWNERDEAD.
Note - Your application must always check the return code from pthread_mutex_lock() for a mutex initialized with the PTHREAD_MUTEX_ROBUST_NP attribute.
The new owner of this mutex should make the state protected by the mutex consistent. This state might have been left inconsistent when the previous owner terminated.
If the new owner is able to make the state consistent, call pthread_mutex_consistent_np() for the mutex before unlocking the mutex. This marks the mutex as consistent and subsequent calls to pthread_mutex_lock() and pthread_mutex_unlock() will behave in the normal manner.
If the new owner is not able to make the state consistent, do not call pthread_mutex_consistent_np() for the mutex, but unlock the mutex.
All waiters are awakened and all subsequent calls to pthread_mutex_lock() fail to acquire the mutex. The return code is ENOTRECOVERABLE. The mutex can be made consistent by calling pthread_mutex_destroy() to uninitialize the mutex, and calling pthread_mutex_int() to reinitialize the mutex. However, the state that was protected by the mutex remains inconsistent and some form of application recovery is required.
If the thread that acquires the lock with EOWNERDEAD terminates without unlocking the mutex, the next owner acquires the lock with an EOWNERDEAD return code.
On successful completion, pthread_mutexattr_setrobust_np() returns 0. Any other return value indicates that an error occurred.
pthread_mutexattr_setrobust_np() might fail if the following condition occurs:
EINVAL
Description: The value specified by attr or robustness is invalid.
pthread_mutexattr_getrobust_np gets the robust attribute of a mutex attribute object.
#include <pthread.h> int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *attr, int *robustness);
attr points to the mutex attribute object previously created by a call to pthread_mutexattr_init().
robustness is the value of the robust attribute of a mutex attribute object.
On successful completion, pthread_mutexattr_getrobust_np() returns 0. Any other return value indicates that an error occurred.
pthread_mutexattr_getrobust_np() might fail if the following condition occurs:
EINVAL
Description: The value specified by attr or robustness is invalid.