Sun Microsystems Logo
Products and Services
 
Support and Training
 
 

Previous Previous     Contents     Index     Next Next

Unlock a Read-Write Lock

rw_unlock(3THR)

#include <synch.h>  (or #include <thread.h>)

int rw_unlock(rwlock_t *rwlp);

Use rw_unlock(3THR) to unlock a read-write lock pointed to by 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 them is unblocked. (For POSIX threads, see pthread_rwlock_unlock(3THR).)

Return Values

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

Invalid argument.

 

EFAULT

rwlp points to an illegal address.

Destroy Read-Write Lock State

rwlock_destroy(3THR)

#include <synch.h>  (or #include <thread.h>)

int rwlock_destroy(rwlock_t *rwlp);

Use rwlock_destroy(3THR) to destroy any state associated with the read-write lock pointed to by rlwp. The space for storing the read-write lock is not freed. (For POSIX threads, see pthread_rwlock_destroy(3THR).)

Return Values

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

Invalid argument.

 

EFAULT

rwlp points to an illegal address.

Read-Write Lock Example

Example 8-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 8-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);
}


Similar Solaris Threads Functions

Table 8-3 Similar Solaris Threads Functions

Operation

Destination Discussion

Create a thread

thr_create(3THR)

Get the minimal stack size

thr_min_stack(3THR)

Get the thread identifier

thr_self(3THR)

Yield thread execution

thr_yield(3THR)

Send a signal to a thread

thr_kill(3THR)

Access the signal mask of the calling thread

thr_sigsetmask(3THR)

Terminate a thread

thr_exit(3THR)

Wait for thread termination

thr_join(3THR)

Create a thread-specific data key

thr_keycreate(3THR)

Set thread-specific data

thr_setspecific(3THR)

Get thread-specific data

thr_getspecific(3THR)

Set the thread priority

thr_setprio(3THR)

Get the thread priority

thr_getprio(3THR)

Create a Thread

The thr_create(3THR) routine is one of the most elaborate of all the Solaris threads library routines.

thr_create(3THR)

Usethr_create(3THR) to add a new thread of control to the current process. (For POSIX threads, see pthread_create(3THR).)

Note that the new thread does not inherit pending signals, but it does inherit priority and signal masks.

#include <thread.h>

int thr_create(void *stack_base, size_t stack_size,
    void *(*start_routine) (void *), void *arg, long flags,
    thread_t *new_thread);

size_t thr_min_stack(void);

stack_base--Contains the address for the stack that the new thread uses. If stack_base is NULL then thr_create() allocates a stack for the new thread with at least stack_size bytes.

stack_size--Contains the size, in number of bytes, for the stack that the new thread uses. If stack_size is zero, a default size is used. In most cases, a zero value works best. If stack_size is not zero, it must be greater than the value returned by thr_min_stack().

There is no general need to allocate stack space for threads. The threads library allocates 1 megabyte of virtual memory for each thread's stack with no swap space reserved. (The library uses the -MAP_NORESERVE option of mmap(2) to make the allocations.)

start_routine--Contains the function with which the new thread begins execution. When start_routine() returns, the thread exits with the exit status set to the value returned by start_routine (see thr_exit(3THR)).

arg--Can be anything that is described by void, which is typically any 4-byte value. Anything larger must be passed indirectly by having the argument point to it.

Note that you can supply only one argument. To get your procedure to take multiple arguments, encode them as one (such as by putting them in a structure).

flags--Specifies attributes for the created thread. In most cases a zero value works best.

The value in flags is constructed from the bitwise inclusive OR of the following:

  • THR_SUSPENDED--Suspends the new thread and does not execute start_routine until the thread is started by thr_continue(). Use this to operate on the thread (such as changing its priority) before you run it. The termination of a detached thread is ignored.

  • THR_DETACHED--Detaches the new thread so that its thread ID and other resources can be reused as soon as the thread terminates. Set this when you do not want to wait for the thread to terminate.


Note - When there is no explicit synchronization to prevent it, an unsuspended, detached thread can die and have its thread ID reassigned to another new thread before its creator returns from thr_create().


  • THR_BOUND--Permanently binds the new thread to an LWP (the new thread is a bound thread).

  • THR_DAEMON--Marks the new thread as a daemon. A daemon thread is always detached (THR_DAEMON implies THR_DETACHED). The process exits when all nondaemon threads exit. Daemon threads do not affect the process exit status and are ignored when counting the number of thread exits.

    A process can exit either by calling exit() or by having every thread in the process that was not created with the THR_DAEMON flag call thr_exit(3THR). An application, or a library it calls, can create one or more threads that should be ignored (not counted) in the decision of whether to exit. The THR_DAEMON flag identifies threads that are not counted in the process exit criterion.

Previous Previous     Contents     Index     Next Next