thread(3thread) thread(3thread)
NAME
thread - introduction to the Threads Library
SYNOPSIS
cc [options] -Kthread file
#include <thread.h>
DESCRIPTION
Threads
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(3synch)] are provided that allow
coordination of threads either within a process or across
processes.
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(2)]. 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(3thread) or with thr_setconcurrency(3thread).
A thread can also be bound to an LWP for its lifetime [see
thr_create(3thread)]. 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).
Copyright 1994 Novell, Inc. Page 1
thread(3thread) thread(3thread)
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(3synch)], bound threads are given
scheduling priority over multiplexed threads to make better
use of system resources.
Thread Creation
thr_create(3thread) 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 may 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(3thread) 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(2), threads create siblings for which they do not
have to wait. Sibling threads may be awaited with
thr_join(3thread) (see below), but this is optional.
Daemon Threads
An application creates daemon threads (also known as detached
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(3thread) causes the calling thread to terminate its
execution.
A process containing threads will terminate in any of the
following four circumstances:
When the last non-daemon thread terminates, the process
exits.
Copyright 1994 Novell, Inc. Page 2
thread(3thread) thread(3thread)
If any thread calls exit(2) directly, the process and
all its threads and LWPs will exit immediately.
If the initial thread terminates without calling
thr_exit, exit will be called implicitly, causing the
entire process to exit.
If the thread receives a signal whose disposition is to
terminate the process, the process will exit.
Joining or Waiting for a Thread
A thread uses thr_join(3thread) 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(3thread)], they cannot be
joined.
Thread Scheduling
The Threads Library supports three scheduling policies:
time-sharing (SCHED_TS or SCHED_OTHER)
round-robin (SCHED_RR)
first-in-first-out (SCHED_FIFO)
Multiplexed threads must run under the time-sharing policy.
Bound threads can run under any of the policies. See
thr_setscheduler(3thread) 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(3thread) and its priority only with
thr_setprio(3thread). It can retrieve its scheduling policy
and priority with thr_getscheduler(3thread) and its priority
only with thr_getprio(3thread). thr_yield(3thread) 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.
Copyright 1994 Novell, Inc. Page 3
thread(3thread) thread(3thread)
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(3thread) 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(2) or by using
signal(2), sigset [see signal(2)], or sigaction(2) to
establish a handler for a signal.
Threads use thr_kill(3thread) 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(3thread),
thr_keycreate(3thread), thr_keydelete(3thread), and
thr_setspecific(3thread).
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(3synch)] can be traced. Significant information, such
as arguments, return values, lock contention, and duration of
execution are recorded.
Copyright 1994 Novell, Inc. Page 4
thread(3thread) thread(3thread)
To avoid a performance penalty on the Threads Library, a
separate library, libthreadT.so, contains the tracing
routines. To obtain trace data, the application must be
linked to libthreadT.so.
See thread_trace(4) for a description of trace data files.
USAGE
Warnings
The Threads Library does not guarantee to preserve errno
across calls.
REFERENCES
exit(2), _lwp_create(2), sigaction(2), signal(2), sigwait(2),
synch(3synch), thread_trace(4), thr_continue(3thread),
thr_create(3thread), thr_exit(3thread),
thr_getconcurrency(3thread), thr_getprio(3thread),
thr_get_rr_interval(3thread), thr_getscheduler(3thread),
thr_getspecific(3thread), thr_join(3thread),
thr_keycreate(3thread), thr_keydelete(3thread),
thr_kill(3thread), thr_minstack(3thread), thr_self(3thread),
thr_setconcurrency(3thread), thr_setprio(3thread),
thr_setscheduler(3thread), thr_setspecific(3thread),
thr_sigsetmask(3thread), thr_suspend(3thread),
thr_yield(3thread)
Copyright 1994 Novell, Inc. Page 5