Thread life cycle

Updated: October 26, 2022

The number of threads within a process can vary widely, with threads being created and destroyed dynamically.

Thread creation (pthread_create()) involves allocating and initializing the necessary resources within the process's address space (e.g., thread stack) and starting the execution of the thread at some function in the address space.

Thread termination (pthread_exit(), pthread_cancel()) involves stopping the thread and reclaiming the thread's resources. As a thread executes, its state can generally be described as either “ready” or “blocked.” More specifically, it can be one of the following:

Figure 1. Possible thread states. Note that, in addition to the transitions shown above, a thread can move from any state (except DEAD) to READY.
STATE_CONDVAR
The thread is blocked on a condition variable (e.g., it called pthread_cond_wait()).
STATE_DEAD
The thread has terminated and is waiting for a join by another thread.
STATE_INTR
The thread is blocked waiting for an interrupt (i.e., it called InterruptWait()).
STATE_JOIN
The thread is blocked waiting to join another thread (e.g., it called pthread_join()).
STATE_MUTEX
The thread is blocked on a mutual exclusion lock (e.g., it called pthread_mutex_lock()).
STATE_NANOSLEEP
The thread is sleeping for a short time interval (e.g., it called nanosleep()).
STATE_NET_REPLY
The thread is waiting for a reply to be delivered across the network (i.e., it called MsgReply*()).
STATE_NET_SEND
The thread is waiting for a pulse or signal to be delivered across the network (i.e., it called MsgSendPulse(), MsgDeliverEvent(), or SignalKill()).
STATE_READY
The thread is waiting to be executed while the processor executes another thread of equal or higher priority.
STATE_RECEIVE
The thread is blocked on a message receive (e.g., it called MsgReceive()).
STATE_REPLY
The thread is blocked on a message reply (i.e., it called MsgSend(), and the server received the message).
STATE_RUNNING
The thread is being executed by a processor. The kernel uses an array (with one entry per processor in the system) to keep track of the running threads.
STATE_SEM
The thread is waiting for a semaphore to be posted (i.e., it called SyncSemWait()).
STATE_SEND
The thread is blocked on a message send (e.g., it called MsgSend(), but the server hasn't yet received the message).
STATE_SIGSUSPEND
The thread is blocked waiting for a signal (i.e., it called sigsuspend()).
STATE_SIGWAITINFO
The thread is blocked waiting for a signal (i.e., it called sigwaitinfo()).
STATE_STACK
The thread is waiting for the virtual address space to be allocated for the thread's stack (parent will have called ThreadCreate()).
STATE_STOPPED
The thread is blocked waiting for a SIGCONT signal.
STATE_WAITCTX
The thread is waiting for a noninteger (e.g., floating point) context to become available for use.
STATE_WAITPAGE
The thread is waiting for physical memory to be allocated for a virtual address.
STATE_WAITTHREAD
The thread is waiting for a child thread to finish creating itself (i.e., it called ThreadCreate()).

In discussion and in the documentation, we usually omit the “STATE_” prefix.