This article is from the Threads Programming FAQ, by Bryan O'Sullivan firstname.lastname@example.org with numerous contributions by others.
User-space threads live without any support from the kernel; they
maintain all of their state in user space. Since the kernel does not
know about them, they cannot be scheduled to run on multiple
processors in parallel.
Kernel-supported threads fall into two classes.
* In a "pure" kernel-supported system, the kernel is responsible for
scheduling all threads.
* Systems in which the kernel cooperates with a user-level library
to do scheduling are known as "two-level", or "hybrid", systems.
Typically, the kernel schedules LWPs, and the user-level library
schedules threads onto LWPs.
Because of its performance problems (caused by the need to cross the
user/kernel protection boundary twice for "every" thread context
switch), the former class has fewer members than does the latter (at
least on Unix variants). Both classes allow threads to be run across
multiple processors in parallel.