JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Multithreaded Programming Guide     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information

Preface

1.  Covering Multithreading Basics

2.  Basic Threads Programming

3.  Thread Attributes

4.  Programming with Synchronization Objects

Mutual Exclusion Lock Attributes

Initializing a Mutex Attribute Object

pthread_mutexattr_init Syntax

pthread_mutexattr_init Return Values

Destroying a Mutex Attribute Object

pthread_mutexattr_destroy Syntax

pthread_mutexattr_destroy Return Values

Setting the Scope of a Mutex

pthread_mutexattr_setpshared Syntax

pthread_mutexattr_setpshared Return Values

Getting the Scope of a Mutex

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_mutexattr_getrobust_np Syntax

pthread_mutexattr_getrobust_np Return Values

Using Mutual Exclusion Locks

Initializing a Mutex

pthread_mutex_init Syntax

pthread_mutex_init Return Values

Making a Mutex Consistent

pthread_mutex_consistent_np Syntax

pthread_mutex_consistent_np Return Values

Locking a Mutex

pthread_mutex_lock Syntax

pthread_mutex_lock Return Values

Unlocking a Mutex

pthread_mutex_unlock Syntax

pthread_mutex_unlock Return Values

Locking a Mutex Without Blocking

pthread_mutex_trylock Syntax

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

Destroying a Mutex

pthread_mutex_destroy Syntax

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

Using Spin Locks

Initializing a Spin Lock

pthread_spin_init() Syntax

pthread_spin_init() Return Values

Acquiring a Spin Lock

pthread_spin_lock() Syntax

pthread_spin_lock() Return Values

Acquiring a Non-Blocking Spin Lock

pthread_spin_trylock() Syntax

pthread_spin_trylock() Return Values

Unlocking a Spin Lock

pthread_spin_unlock() Syntax

pthread_spin_unlock() Return Values

Destroying a Spin Lock

pthread_spin_destroy() Syntax

pthread_spin_destroy() Return Values

Condition Variable Attributes

Initializing a Condition Variable Attribute

pthread_condattr_init Syntax

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

Using Condition Variables

Initializing a Condition Variable

pthread_cond_init Syntax

pthread_cond_init Return Values

Blocking on a Condition Variable

pthread_cond_wait Syntax

pthread_cond_wait Return Values

Unblocking One Thread

pthread_cond_signal Syntax

pthread_cond_signal Return Values

Blocking Until a Specified Time

pthread_cond_timedwait Syntax

pthread_cond_timedwait Return Values

Blocking For a Specified Interval

pthread_cond_reltimedwait_np Syntax

pthread_cond_reltimedwait_np Return Values

Unblocking All Threads

pthread_cond_broadcast Syntax

pthread_cond_broadcast Return Values

Destroying the Condition Variable State

pthread_cond_destroy Syntax

pthread_cond_destroy Return Values

Lost Wake-Up Problem

Producer and Consumer Problem

Synchronization With Semaphores

Named and Unnamed Semaphores

Counting Semaphores Overview

Initializing a Semaphore

sem_init Syntax

Initializing Semaphores With Intraprocess Scope

Initializing Semaphores With Interprocess Scope

sem_init Return Values

Incrementing a Semaphore

sem_post Syntax

sem_post Return Values

Blocking on a Semaphore Count

sem_wait Syntax

sem_wait Return Values

Decrementing a Semaphore Count

sem_trywait Syntax

sem_trywait Return Values

Destroying the Semaphore State

sem_destroy Syntax

sem_destroy Return Values

Producer and Consumer Problem Using Semaphores

Read-Write Lock Attributes

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

Using Read-Write Locks

Initializing a Read-Write Lock

pthread_rwlock_init Syntax

pthread_rwlock_init Return Values

Acquiring the Read Lock on Read-Write Lock

pthread_rwlock_rdlock Syntax

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 Syntax

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

Unlocking a Read-Write Lock

pthread_rwlock_unlock Syntax

pthread_rwlock_unlock Return Values

Destroying a Read-Write Lock

pthread_rwlock_destroy Syntax

pthread_rwlock_destroy Return Values

Using Barrier Synchronization

Initializing a Synchronization Barrier

pthread_barrier_init() Syntax

pthread_barrier_init() Return Values

Waiting for Threads to Synchronize at a Barrier

pthread_barrier_wait() Syntax

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

Comparing Primitives

5.  Programming With the Oracle Solaris Software

6.  Programming With Oracle Solaris Threads

7.  Safe and Unsafe Interfaces

8.  Compiling and Debugging

9.  Programming Guidelines

A.  Extended Example: A Thread Pool Implementation

Index

Using Read-Write Locks

After the attributes for a read-write lock are configured, you initialize the read-write lock. The following functions are used to initialize or destroy, lock or unlock, or try to lock a read-write lock. The following table lists the functions discussed in this section that manipulate read-write locks.

Table 4-8 Routines that Manipulate Read-Write Locks

Operation
Related Function Description
Initialize a read-write lock
Read lock on read-write lock
Read lock with a nonblocking read-write lock
Write lock on read-write lock
Write lock with a nonblocking read-write lock
Unlock a read-write lock
Destroy a read-write lock

Initializing a Read-Write Lock

Use pthread_rwlock_init(3C) to initialize the read-write lock referenced by rwlock with the attributes referenced by attr.

pthread_rwlock_init Syntax

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, 
          const pthread_rwlockattr_t *restrict attr);

pthread_rwlock_t  rwlock = PTHREAD_RWLOCK_INITIALIZER;

If attr is NULL, the default read-write lock attributes are used. The effect is the same as passing the address of a default read-write lock attributes object. After the lock is initialized, the lock can be used any number of times without being re-initialized. On successful initialization, the state of the read-write lock becomes initialized and unlocked. Results are undefined if pthread_rwlock_init() is called specifying an already initialized read-write lock. Results are undefined if a read-write lock is used without first being initialized.

In cases where default read-write lock attributes are appropriate, the macro PTHREAD_RWLOCK_INITIALIZER can initialize read-write locks that are statically allocated. The effect is equivalent to dynamic initialization by a call to pthread_rwlock_init() with the parameter attr specified as NULL, except that no error checks are performed.

pthread_rwlock_init Return Values

If successful, pthread_rwlock_init() returns zero. Otherwise, an error number is returned to indicate the error.

If pthread_rwlock_init() fails, rwlock is not initialized and the contents of rwlock are undefined.

EINVAL

Description: The value specified by attr or rwlock is invalid.

Acquiring the Read Lock on Read-Write Lock

pthread_rwlock_rdlock(3C) applies a read lock to the read-write lock referenced by rwlock.

pthread_rwlock_rdlock Syntax

#include <pthread.h>

int  pthread_rwlock_rdlock(pthread_rwlock_t *rwlock );

The calling thread acquires the read lock if a writer does not hold the lock and no writers are blocked on the lock. Whether the calling thread acquires the lock when a writer does not hold the lock and writers are waiting for the lock is unspecified. If a writer holds the lock, the calling thread does not acquire the read lock. If the read lock is not acquired, the calling thread blocks. The thread does not return from the pthread_rwlock_rdlock() until the thread can acquire the lock. Results are undefined if the calling thread holds a write lock on rwlock at the time the call is made.

Implementations are allowed to favor writers over readers to avoid writer starvation. The Oracle Solaris implementation favors writers over readers.

A thread can hold multiple concurrent read locks on rwlock The thread can successfully call pthread_rwlock_rdlock() n times. The thread must call pthread_rwlock_unlock() n times to perform matching unlocks.

Results are undefined if pthread_rwlock_rdlock() is called with an uninitialized read-write lock.

A thread signal handler processes a signal delivered to a thread waiting for a read-write lock. On return from the signal handler, the thread resumes waiting for the read-write lock for reading as if the thread was not interrupted.

pthread_rwlock_rdlock Return Values

If successful, pthread_rwlock_rdlock() returns zero. Otherwise, an error number is returned to indicate the error.

EINVAL

Description: The value specified by attr or rwlock is invalid.

Acquiring a Read Lock on a Read-Write Lock Before a Specified Absolute Time

The pthread_rwlock_timedrdlock(3C) function applies a read lock to the read-write lock referenced by rwlock as in the pthread_rwlock_rdlock() function.

pthread_rwlock_timedrdlock Syntax

#include <pthread.h>
#include <time.h>

int  pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock,
          const struct timespec *restrict abs_timeout);

If the lock cannot be acquired without waiting for other threads to unlock the lock, this wait will be terminated when the specified timeout expires. The timeout expires when the absolute time specified by abs_timeout passes, as measured by the CLOCK_REALTIME clock (that is, when the value of that clock equals or exceeds abs_timeout), or if the absolute time specified by abs_timeout has already been passed at the time of the call.

The resolution of the timeout is the resolution of the CLOCK_REALTIME clock. The timespec data type is defined in the <time.h> header. Under no circumstances does the function fail with a timeout if the lock can be acquired immediately. The validity of the timeout parameter need not be checked if the lock can be immediately acquired.

If a signal that causes a signal handler to be executed is delivered to a thread blocked on a read-write lock with a call to pthread_rwlock_timedrdlock(), upon return from the signal handler the thread resumes waiting for the lock as if it was not interrupted.

The calling thread might deadlock if at the time the call is made it holds a write lock on rwlock.

The pthread_rwlock_reltimedrdlock_np() function is identical to the pthread_rwlock_timedrdlock() function, except that the timeout is specified as a relative time interval.

pthread_rwlock_timedrdlock Return Values

If successful, returns 0 if the lock for writing on the read-write lock object referenced by rwlock is acquired. Otherwise, an error number is returned to indicate the error.

ETIMEDOUT

Description: The lock could not be acquired before the specified timeout expired.

EAGAIN

Description: The read lock could not be acquired because the maximum number of read locks for lock would be exceeded.

EDEADLK

Description: The calling thread already holds the rwlock.

EINVAL

Description: The value specified by rwlock does not refer to an initialized read-write lock object, or the timeout nanosecond value is less than zero or greater than or equal to 1,000 million.

Acquiring a Non-Blocking Read Lock on a Read-Write Lock

pthread_rwlock_tryrdlock(3C) applies a read lock as in pthread_rwlock_rdlock() with the exception that the function fails if any thread holds a write lock on rwlock or writers are blocked on rwlock.

pthread_rwlock_tryrdlock Syntax

#include <pthread.h>

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

pthread_rwlock_tryrdlock Return Values

pthread_rwlock_tryrdlock() returns zero if the lock for reading on the read-write lock object referenced by rwlock is acquired. If the lock is not acquired, an error number is returned to indicate the error.

EBUSY

Description: The read-write lock could not be acquired for reading because a writer holds the lock or was blocked on it.

Acquiring the Write Lock on a Read-Write Lock

pthread_rwlock_wrlock(3C) applies a write lock to the read-write lock referenced by rwlock.

pthread_rwlock_wrlock Syntax

#include <pthread.h>

int  pthread_rwlock_wrlock(pthread_rwlock_t *rwlock );

The calling thread acquires the write lock if no other reader thread or writer thread holds the read-write lock rwlock. Otherwise, the thread blocks. The thread does not return from the pthread_rwlock_wrlock() call until the thread can acquire the lock. Results are undefined if the calling thread holds the read-write lock, either a read lock or write lock, at the time the call is made.

Implementations are allowed to favor writers over readers to avoid writer starvation. The Oracle Solaris implementation favors writers over readers.

Results are undefined if pthread_rwlock_wrlock() is called with an uninitialized read-write lock.

The thread signal handler processes a signal delivered to a thread waiting for a read-write lock for writing. Upon return from the signal handler, the thread resumes waiting for the read-write lock for writing as if the thread was not interrupted.

pthread_rwlock_wrlock Return Values

pthread_rwlock_rwlock() returns zero if the lock for writing on the read-write lock object referenced by rwlock is acquired. If the lock is not acquired, an error number is returned to indicate the error.

Acquiring a Non-blocking Write Lock on a Read-Write Lock

pthread_rwlock_trywrlock(3C) applies a write lock like pthread_rwlock_wrlock(), with the exception that the function fails if any thread currently holds rwlock, for reading or writing.

pthread_rwlock_trywrlock Syntax

#include <pthread.h>

int pthread_rwlock_trywrlock(pthread_rwlock_t  *rwlock);

Results are undefined if pthread_rwlock_trywrlock() is called with an uninitialized read-write lock.

pthread_rwlock_trywrlock Return Values

If successful, pthread_rwlock_trywrlock() returns zero if the lock for writing on the read-write lock object referenced by rwlock is acquired. Otherwise, an error number is returned to indicate the error.

EBUSY

Description: The read-write lock could not be acquired for writing because the read-write lock is already locked for reading or writing.

Acquiring a Write Lock on a Read-Write Lock Before a Specified Absolute Time

The pthread_rwlock_timedwrlock(3C) function applies a write lock to the read-write lock referenced by rwlock as in the pthread_rwlock_wrlock() function, but attempts to apply the lock only until a specified absolute time.

pthread_rwlock_timedwrlock Syntax

#include <pthread.h>
#include <time.h>

int  pthread_rwlock_timedwrlock(pthread_rwlock_t   *restrict rwlock, 
     const struct timespec *restrict abs_timeout);

The calling thread acquires the write lock if no other reader thread or writer thread holds the read-write lock rwlock. If the lock cannot be acquired without waiting for other threads to unlock the lock, this wait will be terminated when the specified timeout expires. The timeout expires when the absolute time specified by abs_timeoutpasses, as measured by the CLOCK_REALTIME clock (that is, when the value of that clock equals or exceeds abs_timeout) or if the absolute time specified by abs_timeout has already been passed at the time of the call. The pthread_rwlock_reltimedwrlock_np() function is identical to the pthread_rwlock_timedwrlock() function, except that the timeout is specified as a relative time interval.

pthread_rwlock_timedwrlock Returns

If successful, returns 0 if the lock for writing on the read-write lock object referenced by rwlock is acquired. Otherwise, an error number is returned to indicate the error.

ETIMEDOUT

Description: The lock could not be acquired before the specified timeout expired.

EDEADLK

Description: The calling thread already holds the rwlock.

EINVAL

Description: The value specified by rwlock does not refer to an initialized read-write lock object, or the timeout nanosecond value is less than zero or greater than or equal to 1,000 million.

Unlocking a Read-Write Lock

pthread_rwlock_unlock(3C) releases a lock held on the read-write lock object referenced by rwlock.

pthread_rwlock_unlock Syntax

#include <pthread.h>

int pthread_rwlock_unlock (pthread_rwlock_t  *rwlock);

Results are undefined if the read-write lock rwlock is not held by the calling thread.

If pthread_rwlock_unlock() is called to release a read lock from the read-write lock object, and other read locks are currently held on this lock object, the object remains in the read locked state. If pthread_rwlock_unlock() releases the calling thread's last read lock on this read-write lock object, the calling thread is no longer an owner of the object. If pthread_rwlock_unlock() releases the last read lock for this read-write lock object, the read-write lock object is put in the unlocked state with no owners.

If pthread_rwlock_unlock() is called to release a write lock for this read-write lock object, the lock object is put in the unlocked state with no owners.

If pthread_rwlock_unlock() unlocks the read-write lock object and multiple threads are waiting to acquire the lock object for writing, the scheduling policy determines which thread acquires the object for writing. If multiple threads are waiting to acquire the read-write lock object for reading, the scheduling policy determines the order the waiting threads acquire the object for reading. If multiple threads are blocked on rwlock for both read locks and write locks, whether the readers or the writer acquire the lock first is unspecified.

Results are undefined if pthread_rwlock_unlock() is called with an uninitialized read-write lock.

pthread_rwlock_unlock Return Values

If successful, pthread_rwlock_unlock() returns zero. Otherwise, an error number is returned to indicate the error.

Destroying a Read-Write Lock

pthread_rwlock_destroy(3C) destroys the read-write lock object referenced by rwlock and releases any resources used by the lock.

pthread_rwlock_destroy Syntax

#include <pthread.h>

int pthread_rwlock_destroy(pthread_rwlock_t **rwlock);

The effect of subsequent use of the lock is undefined until the lock is re-initialized by another call to pthread_rwlock_init(). An implementation can cause pthread_rwlock_destroy() to set the object referenced by rwlock to an invalid value. Results are undefined if pthread_rwlock_destroy() is called when any thread holds rwlock. Attempting to destroy an uninitialized read-write lock results in undefined behavior. A destroyed read-write lock object can be re-initialized using pthread_rwlock_init(). The results of otherwise referencing the read-write lock object after the lock object has been destroyed are undefined.

pthread_rwlock_destroy Return Values

If successful, pthread_rwlock_destroy() returns zero. Otherwise, an error number is returned to indicate the error.

EINVAL

Description: The value specified by attr or rwlock is invalid.