Figure 5.7 shows the mapping of Pthreads threads (left column) to kernel entities (middle column) to physical processors (right column). In this case, the process has four Pthreads threads, labeled "Pthread 1" through "Pthread 4." The Pthreads library creates some number of kernel entities at initialization (and may create more later). Typically, the library will start with one kernel entity (labeled "kernel entity 1" and "kernel entity 2") for each physical processor. The kernel schedules these kernel entities (along with those from other processes) onto the
FIGURE 5.7
two physical processors, labeled "processor 1" and "processor 2." The important characteristics ofthis model are shown in Table 5.4.
Advantages | Disadvantages |
Can take advantage of multiprocessor hardware within a process. | More complicated than other models. |
Most context switches are in user mode (fast). | Programmers lose direct control over kernel entities, since the thread's priority may be meaningful only in user mode. |
Scales well; a process may use one kernel entity per physical processor, or "a few" more. | |
Little latency during system service blocking. |
TABLE 5.4
6 POSIX adjusts to threads
"Who are you?" said the Caterpillar.
This was not an encouraging opening for a conversation.
Alice replied, rather shyly, "I—I hardly know, Sir,
just at present - at least I know who I was when I got up this morning, but
I think I must have been changed several times since then."
Pthreads changes the meaning of a number of traditional POSIX process functions. Most of the changes are obvious, and you'd probably expect them even if the standard hadn't added specific wording. When a thread blocks for I/O, for example, only the calling thread blocks, while other threads in the process can continue to run.
But there's another class of POSIX functions that doesn't extend into the threaded world quite so unambiguously. For example, when you fork a threaded process, what happens to the threads? What does exec do in a threaded process? What happens when one of the threads in a threaded process calls exit?
6.1 fork
Avoid using fork in a threaded program (if you can) unless you intend to exec a new program immediately.
When a threaded process calls fork to create a child process, Pthreads specifies that only the thread calling fork exists in the child. Although only the calling thread exists on return from fork in the child process, all other Pthreads states remain as they were at the time of the call to fork. In the child process, the thread has the same thread state as in the parent. It owns the same mutexes, has the same value for all thread-specific data keys, and so forth. All mutexes and condition variables exist, although any threads that were waiting on a synchronization object at the time of the fork are no longer waiting. (They don't exist in the child process, so how could they be waiting?)
Pthreads does not "terminate" the other threads in a forked process, as ifthey exited with pthread_exit or even as if they were canceled. They simply cease to exist. That is, the threads do not run thread-specific data destructors or cleanup handlers. This is not a problem if the child process is about to call exec to run a new program, but if you use fork to clone a threaded program, beware that you may lose access to memory, especially heap memory stored only as thread-specific data values.
The state of mutexes is not affected by a fork. If it was locked in the parent it is locked in the child!
If a mutex was locked at the time of the call to fork, then it is still locked in the child. Because a locked mutex is