Intro -- introduction to the Threads Library


   cc [options] -Kthread file

#include <thread.h>



The Threads Library supplies routines for thread management that allow a programmer to implement parallel algorithms conveniently. In addition, user-level synchronization routines [see synch(SYNCH)] are provided that allow coordination of threads either within a process or across processes.

The (3thread) and (3synch) man pages describe the UNIX International Threads APIs. The POSIX Threads APIs are described in the (3pthread) man pages. It is good practice to use either one or the other set consistently in an application.

What is a thread?

A thread-of-control, or thread for short, is a sequence of instructions and associated data that is scheduled and executed as an independent entity. Every UNIX process linked with the Threads Library contains at least one, and possibly many, threads. Threads within a process share the address space of the process.

Processes also contain one or more lightweight processes (LWPs), which are independently scheduled by the operating system kernel, and which share address space and other resources. [see _lwp_create(S)]. LWPs are the execution entities for threads. When a thread executes, it is bound to an LWP. We also say that an LWP picks up a thread for execution.

Bound and multiplexed threads

By default, the Threads Library multiplexes threads onto LWPs. That is, when a thread runs, it will be temporarily bound to any LWP in a pool of available LWPs within the process. The number of LWPs available in the pool is called the degree or the level of concurrency. Users can request a change in the level of concurrency with the THR_INCR_CONC flag to thr_create(THREAD) or with thr_setconcurrency(THREAD).

A thread can also be bound to an LWP for its lifetime [see thr_create(THREAD)]. Bound threads have the properties of the underlying LWP, therefore, a bound thread uses operating system scheduling. The Threads Library schedules multiplexed threads (see ``Thread Scheduling,'' below).

When a program is linked with the Threads Library, an initial thread is created to execute the main function. This initial thread is a multiplexed thread.

In certain cases, such as when competing for synchronization objects [see synch(SYNCH)], bound threads are given scheduling priority over multiplexed threads to make better use of system resources.

Thread creation

thr_create(THREAD) creates new threads. Both multiplexed and bound threads can be created. The caller can supply a stack for the thread to run on, or the library will supply one. The library does not check for stack overflow for stacks supplied by the user, but a SIGSEGV signal can be generated if a thread overflows a library-allocated stack.

Every thread has an ID, which is recognized only within the current process. thr_self(THREAD) returns the ID of the calling thread.

Sibling threads

Threads within a process are siblings. Unlike processes, where a parent process creates a child process for which it must wait(S), threads create siblings for which they do not have to wait. Sibling threads can be awaited with thr_join(THREAD) (see below), but this is optional.

Daemon threads

An application creates daemon threads to provide ongoing services, for example asynchronous I/O, for other threads. Daemon threads do not need to exit explicitly; when the last non-daemon thread terminates, the process will exit, terminating any daemon threads.

Thread exit and process exit

thr_exit(THREAD) causes the calling thread to terminate its execution.

A process containing threads will terminate in any of the following four circumstances:

Joining or waiting for a thread

A thread uses thr_join(THREAD) to wait for another thread to exit and to retrieve its exit value. The term ``join'' emphasizes the sibling relationship between threads. When one thread waits for another, in effect they join control paths. Threads are joinable by default, but if they are created with the THR_DETACHED flag [see thr_create(THREAD)], they cannot be joined. If a thread will not be joined, it should be created with the THR_DETACHED flag to allow resources associated with the thread to be reused after the thread terminates.

Thread scheduling

The Threads Library supports three scheduling policies:

Multiplexed threads must run under the time-sharing policy. Bound threads can run under any of the policies. See thr_setscheduler(THREAD) for details. SCHED_TS does not alter the scheduling priority within the process of a multiplexed thread.

A thread can set its scheduling policy and priority with thr_setscheduler(THREAD) and its priority only with thr_setprio(THREAD). It can retrieve its scheduling policy and priority with thr_getscheduler(THREAD) and its priority only with thr_getprio(THREAD). thr_yield(THREAD) causes a thread to stop executing to allow another eligible thread to run.

The Threads Library does not protect against priority inversion. That is, it is possible for a thread to be blocked waiting for a lower priority thread to release a resource.

Error handling

None of the Threads Library routines set errno; most return an error number if an error is encountered. This discourages use of errno, which is non-reentrant and inefficient in a multithreaded environment. The Threads Library does not guarantee to preserve errno across calls.

Signal handling

UNIX System signals were designed for inter-process communication. They have been enhanced to work with multithreaded programs, but their use here should be restricted. We recommend that only a limited number of threads within a process access and receive signals. These threads can convert the notification provided by signals into internal communication between threads.

Each thread in a process has its own signal mask, which is inherited from its creator thread. Threads can use thr_sigsetmask(THREAD) to modify their signal masks.

When a multithreaded process receives a signal, the signal is delivered to one thread interested in the signal. Threads express interest in a signal by calling sigwait(S) or by using signal(S), sigset [see signal(S)], or sigaction(S) to establish a handler for a signal.

Threads use thr_kill(THREAD) to send a signal to a sibling thread.

Thread-Specific data

Thread-specific data routines provide a thread-safe alternative to static or external data. That is, they provide a way for threads to create and access private data that persist across function calls. The thread-specific data routines are: thr_getspecific(THREAD), thr_keycreate(THREAD), thr_keydelete(THREAD), and thr_setspecific(THREAD).

Tracing mechanism

The Threads Library provides a mechanism for tracing significant library events. Calls to all Threads Library interfaces [including the user synchronization interfaces, see synch(SYNCH)] can be traced. Significant information, such as arguments, return values, lock contention, and duration of execution are recorded.

To avoid a performance penalty on the Threads Library, a separate library,, contains the tracing routines. To obtain trace data, the application must be linked to

See thread_trace(F) for a description of trace data files.

Additional sources of information

These books discuss the use of the Threads library (3thread) and (3synch) and the Pthreads library (3pthread), and provide code examples. As always, the UnixWare manual pages give the definitive information on syntax and return values for these interfaces should there be differences.


The Threads Library does not guarantee to preserve errno across calls.


exit(S), _lwp_create(S), sigaction(S), signal(S), sigwait(S), synch(SYNCH), thread_trace(F), thr_continue(THREAD), thr_create(THREAD), thr_exit(THREAD), thr_getconcurrency(THREAD), thr_getprio(THREAD), thr_get_rr_interval(THREAD), thr_getscheduler(THREAD), thr_getspecific(THREAD), thr_join(THREAD), thr_keycreate(THREAD), thr_keydelete(THREAD), thr_kill(THREAD), thr_minstack(THREAD), thr_self(THREAD), thr_setconcurrency(THREAD), thr_setprio(THREAD), thr_setscheduler(THREAD), thr_setspecific(THREAD), thr_sigsetmask(THREAD), thr_suspend(THREAD), thr_yield(THREAD)

Standards compliance

The threads library is not part of any currently supported standard.

It was developed by UNIX System Laboratories, Inc. and is used by permission.

© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 - 01 June 2005