![]() |
![]() |
| |
User-Level ThreadsThreads are the primary programming interface in multithreaded programming. [User-level threads are so named to distinguish them from kernel-level threads, which are the concern of systems programmers only. Because this book is for application programmers, kernel-level threads are not discussed.] Threads are visible only from within the process, where they share all process resources like address space, open files, and so on. The following state is unique to each thread.
Because threads share the process instructions and most of the process data, a change in shared data by one thread can be seen by the other threads in the process. When a thread needs to interact with other threads in the same process, it can do so without involving the operating environment. By default, threads are lightweight. But, to get more control over a thread (for instance, to control scheduling policy more), the application can bind the thread. When an application binds threads to execution resources, the threads become kernel resources (see System Scope (Bound Threads)for more information). To summarize, user-level threads are:
Lightweight ProcessesThe threads library uses underlying threads of control called lightweight processes that are supported by the kernel. You can think of an LWP as a virtual CPU that executes code or system calls. You usually do not need to concern yourself with LWPs to program with threads. The information here about LWPs is provided as background, so you can understand the differences in scheduling scope, described on Process Scope (Unbound Threads). Much as the stdio library routines such as fopen() and fread() use the open() and read() functions, the threads interface uses the LWP interface, and for many of the same reasons. Lightweight processes (LWPs) bridge the user level and the kernel level. Each process contains one or more LWP, each of which runs one or more user threads. (See Figure 1-1.) Figure 1-1 User-level Threads and Lightweight Processes ![]() Each LWP is a kernel resource in a kernel pool, and is allocated and de-allocated to a thread on a per thread basis. SchedulingPOSIX specifies three scheduling policies: first-in-first-out (SCHED_FIFO), round-robin (SCHED_RR), and custom (SCHED_OTHER). SCHED_FIFO is a queue-based scheduler with different queues for each priority level. SCHED_RR is like FIFO except that each thread has an execution time quota. Both SCHED_FIFO and SCHED_RR are POSIX Realtime extensions. SCHED_OTHER is the default scheduling policy. See LWPs and Scheduling Classesfor information about the SCHED_OTHER policy. Two scheduling scopes are available: process scope for unbound threads and system scope for bound threads. Threads with differing scope states can coexist on the same system and even in the same process. In general, the scope sets the range in which the threads scheduling policy is in effect. Process Scope (Unbound Threads)PTHREAD_SCOPE_PROCESS threads are created as unbound threads. The association of these threads with LWPs is managed by the threads library. In most cases, threads should be PTHREAD_SCOPE_PROCESS. These threads have no restriction to execute on a particular LWP, and are equivalent to Solaris thread created without the THR_BOUND flag. The threads library decides the association between individual threads and LWPs. System Scope (Bound Threads)PTHREAD_SCOPE_SYSTEM threads are created as bound threads. A bound thread is permanently attached to an LWP. Each bound thread is bound to an LWP for the lifetime of the thread. This is equivalent to creating a Solaris thread in the THR_BOUND state. You can bind a thread to use special scheduling attributes with Realtime scheduling. Note - In neither case, bound or unbound, can a thread be directly accessed by or moved to another process. CancellationThread cancellation allows a thread to terminate the execution of any other thread in the process. The target thread (the one being cancelled) can keep cancellation requests pending and can perform application-specific cleanup when it acts upon the cancellation notice. The pthreads cancellation feature permits either asynchronous or deferred termination of a thread. Asynchronous cancellation can occur at any time; deferred cancellation can occur only at defined points. Deferred cancellation is the default type. SynchronizationSynchronization allows you to control program flow and access to shared data for concurrently executing threads. The four synchronization models are mutex locks, read/write locks, condition variables, and semaphores.
Using the 64-bit ArchitectureFor application developers, the major difference between the Solaris 64-bit and 32-bit operating environments is the C-language data type model used. The 64-bit data type uses the LP64 model where longs and pointers are 64-bits wide. All other fundamental data types remain the same as those of the 32-bit implementation. The 32-bit data type uses the ILP32 model where ints, longs, and pointers are 32-bits. The following summary briefly describes the major features and considerations for using the 64-bit environment:
| |
| |