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

5.  Programming With the Oracle Solaris Software

6.  Programming With Oracle Solaris Threads

Comparing APIs for Oracle Solaris Threads and POSIX Threads

Major API Differences

Function Comparison Table

Unique Oracle Solaris Threads Functions

Suspending Thread Execution

thr_suspend Syntax

thr_suspend Return Values

Continuing a Suspended Thread

thr_continue Syntax

thr_continue Return Values

Similar Synchronization Functions: Read-Write Locks

Initialize a Read-Write Lock

rwlock_init Syntax

Initializing Read-Write Locks With Intraprocess Scope

Initializing Read-Write Locks With Interprocess Scope

rwlock_init Return Values

Acquiring a Read Lock

rw_rdlock Syntax

rw_rdlock Return Values

Trying to Acquire a Read Lock

rw_tryrdlock Syntax

rw_tryrdlock Return Values

Acquiring a Write Lock

rw_wrlock Syntax

rw_wrlock Return Values

Trying to Acquire a Write Lock

rw_trywrlock Syntax

rw_trywrlock Return Values

Unlock a Read-Write Lock

rw_unlock Syntax

rw_unlock Return Values

Destroying the Read-Write Lock State

rwlock_destroy Syntax

rwlock_destroy Return Values

Similar Oracle Solaris Threads Functions

Creating a Thread

thr_create Syntax

thr_create Return Values

Getting the Minimal Stack Size

thr_min_stack Syntax

thr_min_stack Return Values

Acquiring the Thread Identifier

thr_self Syntax

thr_self Return Values

Yield Thread Execution

thr_yield Syntax

thr_yield Return Values

Send a Signal to a Thread

thr_kill Syntax

thr_kill Return Values

Access the Signal Mask of the Calling Thread

thr_sigsetmask Syntax

thr_sigsetmask Return Values

Terminate a Thread

thr_exit Syntax

thr_exit Return Values

Wait for Thread Termination

thr_join Syntax

thr_join, Join Specific

thr_join, Join Any

thr_join Return Values

Creating a Thread-Specific Data Key

thr_keycreate Syntax

thr_keycreate Return Values

Setting the Thread-Specific Data Value

thr_setspecific Syntax

thr_setspecific Return Values

Getting the Thread-Specific Data Value

thr_getspecific Syntax

thr_getspecific Return Values

Set the Thread Priority

thr_setprio Syntax

thr_setprio Return Values

Get the Thread Priority

thr_getprio Syntax

thr_getprio Return Values

Similar Synchronization Functions: Mutual Exclusion Locks

Initialize a Mutex

mutex_init(3C) Syntax

Mutexes With Intraprocess Scope

Mutexes With Interprocess Scope

Mutexes With Interprocess Scope-Robust

mutex_init Return Values

Destroy a Mutex

mutex_destroy Syntax

mutex_destroy Return Values

Acquiring a Mutex

mutex_lock Syntax

mutex_lock Return Values

Releasing a Mutex

mutex_unlock Syntax

mutex_unlock Return Values

Trying to Acquire a Mutex

mutex_trylock Syntax

mutex_trylock Return Values

Similar Synchronization Functions: Condition Variables

Initialize a Condition Variable

cond_init Syntax

Condition Variables With Intraprocess Scope

Condition Variables With Interprocess Scope

cond_init Return Values

Destroying a Condition Variable

cond_destroy Syntax

cond_destroy Return Values

Waiting for a Condition

cond_wait Syntax

cond_wait Return Values

Wait for an Absolute Time

cond_timedwait Syntax

cond_timedwait Return Values

Waiting for a Time Interval

cond_reltimedwait Syntax

cond_reltimedwait Return Values

Unblock One Thread

cond_signal Syntax

cond_signal Return Values

Unblock All Threads

cond_broadcast Syntax

cond_broadcast Return Values

Similar Synchronization Functions: Semaphores

Initialize a Semaphore

sema_init Syntax

Semaphores With Intraprocess Scope

Semaphores With Interprocess Scope

sema_init Return Values

Increment a Semaphore

sema_post Syntax

sema_post Return Values

Block on a Semaphore Count

sema_wait Syntax

sema_wait Return Values

Decrement a Semaphore Count

sema_trywait Syntax

sema_trywait Return Values

Destroy the Semaphore State

sema_destroy(3C) Syntax

sema_destroy(3C) Return Values

Synchronizing Across Process Boundaries

Example of Producer and Consumer Problem

Special Issues for fork() and Oracle Solaris Threads

7.  Safe and Unsafe Interfaces

8.  Compiling and Debugging

9.  Programming Guidelines

A.  Extended Example: A Thread Pool Implementation

Index

Similar Oracle Solaris Threads Functions

Table 6-3 Similar Oracle Solaris Threads Functions

Operation
Related Function Description
Create a thread
Get the minimal stack size
Get the thread identifier
Yield thread execution
Send a signal to a thread
Access the signal mask of the calling thread
Terminate a thread
Wait for thread termination
Create a thread-specific data key
Set thread-specific data
Get thread-specific data
Set the thread priority
Get the thread priority

Creating a Thread

The thr_create(3C) routine is one of the most elaborate of all routines in the Oracle Solaris threads interface.

Use thr_create(3C) to add a new thread of control to the current process. For POSIX threads, see pthread_create Syntax.

thr_create Syntax

#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);

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

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, stack_size must be greater than the value returned by thr_min_stack().

In general, you do not need to allocate stack space for threads. The system allocates 1 megabyte of virtual memory for each thread's stack with no reserved swap space. The system 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 Syntax.

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

Note that you can supply only one argument. To get your procedure to take multiple arguments, encode the multiple arguments as a single argument, such as by putting the arguments 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 arguments:


Note - When no explicit synchronization is allocated, an unsuspended, detached thread can fail. On failure, the thread ID is reassigned to another new thread before its creator returns from thr_create().


new_thread. When new_thread is not NULL, it points to where the ID of the new thread is stored when thr_create() is successful. The caller is responsible for supplying the storage pointed to by this argument. The ID is valid only within the calling process.

If you are not interested in this identifier, supply a NULL value to new_thread.

thr_create Return Values

thr_create() returns zero when the function completes successfully. Any other return value indicates that an error occurred. When any of the following conditions is detected, thr_create() fails and returns the corresponding value.

EAGAIN

Description: A system limit is exceeded, such as when too many LWPs have been created.

ENOMEM

Description: Insufficient memory was available to create the new thread.

EINVAL

Description: stack_base is not NULL and stack_size is less than the value returned by thr_min_stack().

Getting the Minimal Stack Size

Use thr_min_stack(3C) to get the minimum stack size for a thread.

Stack behavior in Oracle Solaris threads is generally the same as stack behavior in pthreads. For more information about stack setup and operation, see About Stacks.

thr_min_stack Syntax

#include <thread.h>

size_t thr_min_stack(void);

thr_min_stack() returns the amount of space that is needed to execute a null thread. A null thread is a thread that is created to execute a null procedure. Useful threads need more than the absolute minimum stack size, so be very careful when reducing the stack size.

A thread that executes more than a null procedure should allocate a stack size that is larger than the size of thr_min_stack().

When a thread is created with a user-supplied stack, the user must reserve enough space to run the thread. A dynamically linked execution environment increases the difficulty of determining the thread minimal stack requirements.

You can specify a custom stack in two ways. The first is to supply a NULL for the stack location, thereby asking the runtime library to allocate the space for the stack, but to supply the desired size in the stacksize parameter to thr_create() .

The other approach is to take overall aspects of stack management and supply a pointer to the stack to thr_create(). This means that you are responsible not only for stack allocation but also for stack deallocation. When the thread terminates, you must arrange for the disposal of the thread's stack.

When you allocate your own stack, be sure to append a red zone to its end by calling mprotect(2).

Most users should not create threads with user-supplied stacks. User-supplied stacks exist only to support applications that require complete control over their execution environments.

Instead, users should let the system manage stack allocation. The system provides default stacks that should meet the requirements of any created thread.

thr_min_stack Return Values

No errors are defined.

Acquiring the Thread Identifier

Use thr_self(3C) to get the ID of the calling thread. For POSIX threads, see pthread_self Syntax.

thr_self Syntax

#include <thread.h>

thread_t thr_self(void);

thr_self Return Values

No errors are defined.

Yield Thread Execution

thr_yield(3C) causes the current thread to yield its execution in favor of another thread with the same or greater priority. Otherwise, thr_yield() has no effect. However, calling thr_yield() does not guarantee that the thread yields its execution.

thr_yield Syntax

#include <thread.h>

void thr_yield(void);

thr_yield Return Values

thr_yield() returns nothing and does not set errno .

Send a Signal to a Thread

thr_kill(3C) sends a signal to a thread. For POSIX threads, see pthread_kill Syntax.

thr_kill Syntax

#include <thread.h>
#include <signal.h>
int thr_kill(thread_t target_thread, int sig);

thr_kill Return Values

Upon successful completion, thr_kill() returns 0. When any of the following conditions is detected, thr_kill() fails and returns the corresponding value. When a failure occurs, no signal is sent.

ESRCH

Description: No thread was found associated with the thread designated by thread ID.

EINVAL

Description: The sig argument value is not zero. sig is an invalid or unsupported signal number.

Access the Signal Mask of the Calling Thread

Use thr_sigsetmask(3C) to change or examine the signal mask of the calling thread.

thr_sigsetmask Syntax

#include <thread.h>
#include <signal.h>
int thr_sigsetmask(int how, const sigset_t *set, 
          sigset_t *oset);

thr_sigsetmask() changes or examines a calling thread's signal mask. Each thread has its own signal mask. A new thread inherits the calling thread's signal mask and priority. However, pending signals are not inherited. Pending signals for a new thread will be empty.

If the value of the argument set is not NULL, set points to a set of signals that can modify the currently blocked set. If the value of set is NULL, the value of how is insignificant and the thread's signal mask is unmodified. Use this behavior to inquire about the currently blocked signals.

The value of how specifies the method in which the set is changed. how takes one of the following values.

thr_sigsetmask Return Values

Upon successful completion, thr_sigsetmask() returns 0. When any of the following conditions is detected, thr_sigsetmask() fails and returns the corresponding value.

EINVAL

Description: set is not NULL and the value of how is not defined.

Terminate a Thread

Use thr_exit(3C) to terminate a thread. For POSIX threads, see pthread_exit Syntax.

thr_exit Syntax

#include <thread.h>

void thr_exit(void *status);

thr_exit Return Values

thr_exit() does not return to its caller.

Wait for Thread Termination

Use thr_join(3C) to wait for a target thread to terminate. For POSIX threads, see pthread_join Syntax.

thr_join Syntax

#include <thread.h>

int thr_join(thread_t tid, thread_t *departedid, void **status);

The target thread must be a member of the current process. The target thread cannot be a detached thread or a daemon thread.

Several threads cannot wait for the same thread to complete. One thread will complete successfully. The others will terminate with an ESRCH error.

thr_join() will not block processing of the calling thread if the target thread has already terminated.

thr_join, Join Specific
#include <thread.h>

thread_t tid;
thread_t departedid;
int ret;
void *status;

/* waiting to join thread "tid" with status */
ret = thr_join(tid, &departedid, &status);

/* waiting to join thread "tid" without status */
ret = thr_join(tid, &departedid, NULL);

/* waiting to join thread "tid" without return id and status */
ret = thr_join(tid, NULL, NULL); 

When the tid is (thread_t)0, then thread_join() waits for any undetached thread in the process to terminate. In other words, when no thread identifier is specified, any undetached thread that exits causes thread_join() to return.

thr_join, Join Any
#include <thread.h>

thread_t tid;
thread_t departedid;
int ret;
void *status;

/* waiting to join any non-detached thread with status */
ret = thr_join(0, &departedid, &status); 

By indicating 0 as the thread ID in the Oracle Solaris thr_join(), a join takes place when any non detached thread in the process exits. The departedid indicates the thread ID of the exiting thread.

thr_join Return Values

thr_join() returns 0 if successful. When any of the following conditions is detected, thr_join() fails and returns the corresponding value.

ESRCH

Description: No undetached thread is found which corresponds to the target thread ID.

EDEADLK

Description: A deadlock was detected or the value of the target thread specifies the calling thread.

Creating a Thread-Specific Data Key

thr_keycreate(3C) allocates a key that is used to identify thread-specific data in a process. The key is global to all threads in the process. Each thread binds a value to the key when the key gets created.

Except for the function names and arguments, thread-specific data is the same for Oracle Solaris threads as thread-specific data is for POSIX threads. The synopses for the Oracle Solaris functions are described in this section. For POSIX threads, see pthread_key_create Syntax.

thr_keycreate Syntax

#include <thread.h>

int thr_keycreate(thread_key_t *keyp,
    void (*destructor) (void *value));

keyp independently maintains specific values for each binding thread. Each thread is initially bound to a private element of keyp that allows access to its thread-specific data. Upon key creation, a new key is assigned the value NULL for all active threads. Additionally, upon thread creation, all previously created keys in the new thread are assigned the value NULL.

An optional destructor function can be associated with each keyp. Upon thread exit, if a keyp has a non-NULL destructor and the thread has a non-NULL value associated with keyp , the destructor is called with the currently associated value. If more than one destructor exists for a thread when it exits, the order of destructor calls is unspecified.

thr_keycreate Return Values

thr_keycreate() returns 0 if successful. When any of the following conditions is detected, thr_keycreate() fails and returns the corresponding value.

EAGAIN

Description: The system does not have the resources to create another thread-specific data key, or the number of keys exceeds the per-process limit for PTHREAD_KEYS_MAX.

ENOMEM

Description: Insufficient memory is available to associate value with keyp.

Setting the Thread-Specific Data Value

thr_setspecific(3C) binds value to the thread-specific data key, key, for the calling thread. For POSIX threads, see pthread_setspecific Syntax.

thr_setspecific Syntax

#include <thread.h>

int thr_setspecific(thread_key_t key, void *value);

thr_setspecific Return Values

thr_setspecific() returns 0 if successful. When any of the following conditions is detected, thr_setspecific() fails and returns the corresponding value.

ENOMEM

Description: Insufficient memory is available to associate value with keyp.

EINVAL

Description: keyp is invalid.

Getting the Thread-Specific Data Value

thr_getspecific(3C) stores the current value bound to key for the calling thread into the location pointed to by valuep. For POSIX threads, see pthread_getspecific Syntax.

thr_getspecific Syntax

#include <thread.h>

int thr_getspecific(thread_key_t key, void **valuep);

thr_getspecific Return Values

thr_getspecific() returns 0 if successful. When any of the following conditions is detected, thr_getspecific() fails and returns the corresponding value.

ENOMEM

Description: Insufficient memory is available to associate value with keyp.

EINVAL

Description: keyp is invalid.

Set the Thread Priority

In Oracle Solaris threads, a thread created with a priority other than the priority of its parents is created in SUSPEND mode. While suspended, the thread's priority is modified using the thr_setprio(3C) function call. After thr_setprio() completes, the thread resumes execution.

A higher priority thread receives precedence over lower priority threads with respect to synchronization object contention.

thr_setprio Syntax

thr_setprio(3C) changes the priority of the thread, specified by tid, within the current process to the priority specified by newprio. For POSIX threads, see pthread_setschedparam Syntax.

#include <thread.h>

int thr_setprio(thread_t tid, int newprio)

The range of valid priorities for a thread depends on its scheduling policy.

thread_t tid;
int ret;
int newprio = 20;

/* suspended thread creation */
ret = thr_create(NULL, NULL, func, arg, THR_SUSPENDED, &tid);

/* set the new priority of suspended child thread */
ret = thr_setprio(tid, newprio);

/* suspended child thread starts executing with new priority */
ret = thr_continue(tid);

thr_setprio Return Values

thr_setprio() returns 0 if successful. When any of the following conditions is detected, thr_setprio() fails and returns the corresponding value.

ESRCH

Description: The value specified by tid does not refer to an existing thread.

EINVAL

Description: The value of priority is invalid for the scheduling policy of the specified thread.

EPERM

Description: The caller does not have the appropriate permission to set the priority to the value specified.

Get the Thread Priority

Use thr_getprio(3C) to get the current priority for the thread. Each thread inherits a priority from its creator. thr_getprio() stores the current priority, tid, in the location pointed to by newprio. For POSIX threads, see pthread_getschedparam Syntax.

thr_getprio Syntax

#include <thread.h>

int thr_getprio(thread_t tid, int *newprio)

thr_getprio Return Values

thr_getprio() returns 0 if successful. When the following condition is detected, thr_getprio() fails and returns the corresponding value.

ESRCH

Description: The value specified by tid does not refer to an existing thread.