Jan. 28, 2011, 11:54 p.m.
posted by mark
A thread is a unit of execution within a process. Most modern operating systems provide mechanisms that handle thread lifetime, synchronization, and various other thread-related properties, such as priorities and thread-specific storage. We outline each of these mechanisms below.
Thread lifetime operations. The main thread in a program is created implicitly when a process begins its execution. Most other threads come into existence via explicit calls to thread creation functions, such as pthread_create() (Pthreads) or CreateThread() (Win32). These functions create and start a new thread running a particular entry-point function specified by the caller. As with processes, threads run until they terminate either
Voluntarily, for example, by reaching the end of their entry-point functions or calling a thread exit function, such as pthread_exit() (Pthreads) or ExitThread() (Win32), which allows a thread to set its exit status to a specified value or
Involuntarily, for example, by being killed via a signal or by an asynchronous thread cancelation operation, such as pthread_cancel() (Pthreads) or TerminateThread() (Win32).
Thread synchronization operations. Many OS threading mechanisms allow threads to be created as either:
Detached— When a detached thread exits, the OS reclaims storage used for the thread's state and exit status automatically, or
Joinable— When a joinable thread exits, the OS retains its identity and exit status so that another thread can subsequently synchronize with it to obtain its exit status.
Examples of common thread synchronization mechanisms include
The pthread_join() function in Pthreads
The Win32 functions WaitForSingleObject() and WaitForMultipleObjects()
Some OS platforms provide synchronization functions that allow threads to suspend and resume each other. Some allow threads to send signals to other threads in the same process. However, these operations are generally nonportable and hard to use correctly [But97]; therefore, we don't consider them further in this book, although ACE does encapsulate them on platforms where they exist.
Thread property operations. Most operating systems provide functions to get and set various thread properties. For example, a thread's priority can be examined and changed using the pthread_getschedparam() and pthread_setschedparam() functions in Pthreads as well as the Get-ThreadPriority() and SetThreadPriority() functions in Win32. Likewise, many operating systems allow applications to select more fundamental properties, such as the thread's scheduling class. For instance, Solaris supports both the real-time and time-shared scheduling classes [Kha92] described in Section 5.5.
Thread-specific storage. Thread-specific storage (TSS) is similar in scope to global data; that is, it isn't local to any specific function or object. Unlike global data, however, each thread actually has a separate copy of TSS data. TSS can be used by applications to maintain data that many functions or objects need to access, but that's private to a given thread. A common example is errno, which conveys the error status of system functions. In a multithreaded program, each thread contains a separate copy of errno.
Each TSS item is associated with a key that's global to all threads within a process. These keys are created by a factory function, such as pthread_key_create() (Pthreads) or TlsAlloc() (Win32). Any thread can use the key to access its copy of the storage via a pointer. The key/pointer relationship is managed by TSS functions, such as pthread_setspecific() and pthread_getspecific() in Pthreads or TlsGetvalue() and Tls-SetValue() in Win32.