Multithreaded Programming Guide

Creating and Using Threads

The threads packages will cache the threads data structure and stacks so that the repetitive creation of threads can be reasonably inexpensive.

However, creating and destroying threads as they are required is usually more expensive than managing a pool of threads that wait for independent work.

A good example of this is an RPC server that creates a thread for each request and destroys it when the reply is delivered, instead of trying to maintain a pool of threads to service requests.

While thread creation has less overhead compared to that of process creation, it is not efficient when compared to the cost of a few instructions. Create threads for processing that lasts at least a couple of thousand machine instructions.

Lightweight Processes

Figure 9–1illustrates the relationship between LWPs and the user and kernel levels.

Figure 9–1 Multithreading Levels and Relationships

Diagram showing the relationship between lightweight processes and the user and kernel levels

The user-level threads library ensures that the number of LWPs available is adequate for the currently active user-level threads. The operating environment decides which LWP should run on which processor and when. It has no knowledge about user threads. The kernel schedules LWPs onto CPU resources according to their scheduling classes and priorities.

Each LWP is independently dispatched by the kernel, performs independent system calls, incurs independent page faults, and runs in parallel on a multiprocessor system.

An LWP has some capabilities that are not exported directly to threads, such as a special scheduling class.

The new threads library introduced in Solaris 9 actually assigns one LWP to every thread. This is the same as the alternate libthread in Solaris 8.

The new implementation solves many problems that were inherent in the design of the old threads library, principally in the areas of signal handling and concurrency. The new threads library does not have to be told the desired degree of concurrency via thr_setconcurrency(3THR) because every thread executes on an LWP.

In future Solaris releases, the threads library might reintroduce multiplexing of unbound threads over LWPs, but with the constraints currently in effect for Solaris 9:

Unbound Threads

The library invokes LWPs as needed and assigns them to execute runnable threads. The LWP assumes the state of the thread and executes its instructions. If the thread becomes blocked on a synchronization mechanism, the threads library may save the thread state in process memory and assign another thread to the LWP to run.

Bound Threads

Bound threads are guaranteed to execute on the same LWP from the time the thread is created to the time the thread exits.

Thread Creation Guidelines

Here are some simple guidelines for using threads.