Skip Navigation Links | |
Exit Print View | |
Multithreaded Programming Guide Oracle Solaris 11.1 Information Library |
1. Covering Multithreading Basics
4. Programming with Synchronization Objects
5. Programming With the Oracle Solaris Software
6. Programming With Oracle Solaris Threads
Comparing APIs for Oracle Solaris Threads and POSIX Threads
Unique Oracle Solaris Threads Functions
Similar Synchronization Functions: Read-Write Locks
Initializing Read-Write Locks With Intraprocess Scope
Initializing Read-Write Locks With Interprocess Scope
Trying to Acquire a Write Lock
Similar Oracle Solaris Threads Functions
Getting the Minimal Stack Size
Acquiring the Thread Identifier
Access the Signal Mask of the Calling Thread
Creating a Thread-Specific Data Key
Setting the Thread-Specific Data Value
Getting the Thread-Specific Data Value
Similar Synchronization Functions: Mutual Exclusion Locks
Mutexes With Intraprocess Scope
Mutexes With Interprocess Scope
Mutexes With Interprocess Scope-Robust
Similar Synchronization Functions: Condition Variables
Initialize a Condition Variable
Condition Variables With Intraprocess Scope
Condition Variables With Interprocess Scope
Destroying a Condition Variable
cond_reltimedwait Return Values
Similar Synchronization Functions: Semaphores
Semaphores With Intraprocess Scope
Semaphores With Interprocess Scope
sema_destroy(3C) Return Values
Synchronizing Across Process Boundaries
Example of Producer and Consumer Problem
Special Issues for fork() and Oracle Solaris Threads
Read-write locks allow simultaneous read access by many threads while restricting write access to only one thread at a time. This section discusses the following topics:
Initializing a readers/writer lock
Acquiring a read lock
Trying to acquire a read lock
Acquiring a write lock
Trying to acquire a write
Unlocking a readers/writer lock
Destroying readers/writer lock state
When any thread holds the lock for reading, other threads can also acquire the lock for reading but must wait to acquire the lock for writing. If one thread holds the lock for writing, or is waiting to acquire the lock for writing, other threads must wait to acquire the lock for either reading or writing.
Read-write locks are slower than mutexes. But read-write locks can improve performance when the locks protect data not frequently written but are read by many concurrent threads.
Use read-write locks to synchronize threads in this process and other processes. Allocate read-write locks in memory that is writable and shared among the cooperating processes. See themmap(2) man page for information about mapping read-write locks for this behavior.
By default, the acquisition order is not defined when multiple threads are waiting for a read-write lock. However, to avoid writer starvation, the Oracle Solaris threads package tends to favor writers over readers of equal priority.
Read-write locks must be initialized before use.
Use rwlock_init(3C) to initialize the read-write lock pointed to by rwlp and to set the lock state to unlocked.
#include <synch.h> (or #include <thread.h>) int rwlock_init(rwlock_t *rwlp, int type, void * arg);
type can be one of the following values:
USYNC_PROCESS The read-write lock can be used to synchronize threads in this process and other processes. arg is ignored.
USYNC_THREAD The read-write lock can be used to synchronize threads in this process only. arg is ignored.
Multiple threads must not initialize the same read-write lock simultaneously. Read-write locks can also be initialized by allocation in zeroed memory, in which case a type of USYNC_THREAD is assumed. A read-write lock must not be reinitialized while other threads might be using the lock.
For POSIX threads, see pthread_rwlock_init Syntax .
#include <thread.h> rwlock_t rwlp; int ret; /* to be used within this process only */ ret = rwlock_init(&rwlp, USYNC_THREAD, 0);
#include <thread.h> rwlock_t rwlp; int ret; /* to be used among all processes */ ret = rwlock_init(&rwlp, USYNC_PROCESS, 0);
rwlock_init() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp or arg points to an illegal address.
Use rw_rdlock(3C) to acquire a read lock on the read-write lock pointed to by rwlp.
#include <synch.h> (or #include <thread.h>) int rw_rdlock(rwlock_t *rwlp);
When the read-write lock is already locked for writing, the calling thread blocks until the write lock is released. Otherwise, the read lock is acquired. For POSIX threads, see pthread_rwlock_rdlock Syntax.
rw_rdlock() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.
Use rw_tryrdlock(3C) to attempt to acquire a read lock on the read-write lock pointed to by rwlp.
#include <synch.h> (or #include <thread.h>) int rw_tryrdlock(rwlock_t *rwlp);
When the read-write lock is already locked for writing, rw_tryrdlock() returns an error. Otherwise, the read lock is acquired. For POSIX threads, see pthread_rwlock_tryrdlock Syntax.
rw_tryrdlock() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.
EBUSY
Description: The read-write lock pointed to by rwlp was already locked.
Use rw_wrlock(3C) to acquire a write lock on the read-write lock pointed to by rwlp.
#include <synch.h> (or #include <thread.h>) int rw_wrlock(rwlock_t *rwlp);
When the read-write lock is already locked for reading or writing, the calling thread blocks until all read locks and write locks are released. Only one thread at a time can hold a write lock on a read-write lock. For POSIX threads, see pthread_rwlock_wrlock Syntax.
rw_wrlock() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.
Use rw_trywrlock(3C) to attempt to acquire a write lock on the read-write lock pointed to by rwlp.
#include <synch.h> (or #include <thread.h>) int rw_trywrlock(rwlock_t *rwlp);
When the read-write lock is already locked for reading or writing, rw_trywrlock() returns an error. For POSIX threads, see pthread_rwlock_trywrlock Syntax.
rw_trywrlock() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.
EBUSY
Description: The read-write lock pointed to by rwlp was already locked.
Use rw_unlock(3C) to unlock a read-write lock pointed to by rwlp.
#include <synch.h> (or #include <thread.h>) int rw_unlock(rwlock_t *rwlp);
The read-write lock must be locked, and the calling thread must hold the lock either for reading or writing. When any other threads are waiting for the read-write lock to become available, one of the threads is unblocked. For POSIX threads, see pthread_rwlock_unlock Syntax.
rw_unlock() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.
Use rwlock_destroy(3C) to destroy any state that is associated with the read-write lock pointed to by rlwp.
#include <synch.h> (or #include <thread.h>) int rwlock_destroy(rwlock_t *rwlp);
The space for storing the read-write lock is not freed. For POSIX threads, see pthread_rwlock_destroy Syntax.
Example 6-1 uses a bank account to demonstrate read-write locks. While the program could allow multiple threads to have concurrent read-only access to the account balance, only a single writer is allowed. Note that the get_balance() function needs the lock to ensure that the addition of the checking and saving balances occurs atomically.
Example 6-1 Read-Write Bank Account
rwlock_t account_lock; float checking_balance = 100.0; float saving_balance = 100.0; ... rwlock_init(&account_lock, 0, NULL); ... float get_balance() { float bal; rw_rdlock(&account_lock); bal = checking_balance + saving_balance; rw_unlock(&account_lock); return(bal); } void transfer_checking_to_savings(float amount) { rw_wrlock(&account_lock); checking_balance = checking_balance - amount; saving_balance = saving_balance + amount; rw_unlock(&account_lock); }
rwlock_destroy() returns zero after completing successfully. Any other return value indicates that an error occurred. When any of the following conditions occurs, the function fails and returns the corresponding value.
EINVAL
Description: Invalid argument.
EFAULT
Description: rwlp points to an illegal address.