This article is from the Threads Programming FAQ, by Bryan O'Sullivan firstname.lastname@example.org with numerous contributions by others.
Because the kernel does not know about user threads, there is a danger
that ordinary blocking system calls will block the entire process
(this is "bad") rather than just the calling thread. This means that
user-space threads libraries need to jump through hoops in order to
provide "blocking" system calls that don't block the entire process.
This problem also exists with two-level kernel-supported threads,
though it is not as acute as for user-level threads. What usually
happens here is that system calls block entire LWPs. This means that
if more threads exist than do LWPs and all of the LWPs are blocked in
system calls, then other threads that could potentially make forward
progress are prevented from doing so.
The Solaris threads library provides a reasonable solution to this
problem. If the kernel notices that all LWPs in a process are blocked,
it sends a signal to the process. This signal is caught by the
user-level threads library, which can create another LWP so that the
process will continue to make progress.