There is a clever hack used for blocking system calls in some threads libraries (e.g., DCE
threads in DEC OSF/1) that is worth mentioning. The library puts a jacket routine around each
blocking system call. The jacket routine replaces the blocking system call with a nonblocking one.
Thus, when a thread makes a blocking system call, the library can put that thread to sleep and
allow another one to run. When the signal comes back from the kernel, saying that the system call
is complete, the library figures out which thread made the call and wakes up that sleeping thread,
and everything proceeds as if the thread had blocked in the first place. It's hassle-free async I/O!
"Hassle-free for YOU, maybe. I had to code and debug the monster and I still have to explain it to
users."--Dave Butenhof, reviewing this section.
One Thread per LWP
The one-to-one model allocates one LWP for each thread. This model allows many threads to
run simultaneously on different CPUs. It also allows one or more threads to issue blocking system
calls as the other threads continue to run--even on a uniprocessor.
Remember, when you read about how a vendor implements this model, the vendor may not
distinguish between the thread and the (possibly conceptual) LWP. The vendor may simply refer to
the thread and expect you to understand that it's a single entity containing everything.
This model has the drawback that thread creation involves LWP creation; hence it requires a
system call, as does scheduling and synchronization. In addition, each LWP takes up additional
kernel resources, so you are limited in the total number of threads you can create. Win32 and OS/2
use this model. Some POSIX implementations (DCE, IBM's early threads library, Xavier Leroy's
LinuxThreads) also use it. Any JVMs based on these libraries also use this model, hence Java on
Win32. (A JVM could build a two-level model on top of a one-to-one kernel model, but none
Many Threads on Many LWPs (Strict)
Search WWH :