Many systems implement either the many-to-many or the two-level model place an intermediate data structure between the user and kernel threads. This data structure—typically known as a lightweight process, or LWP—is shown in below Figure. The LWP appears to be a virtual processor on which the application can schedule a user thread to run, to the user-thread library. Each Light Weight Process is attached to a kernel thread, and it is kernel threads that the operating system schedules to run on physical processors. The LWP blocks as well, if a kernel thread blocks (such as while waiting for an I/O operation to complete). The user-level thread attached to the LWP up the chain also blocks.
To run any number of LWPs efficiently, an application may be required. Let’s consider a CPU-bound application running on a single processor. In this scenario, only one thread can run at a time, so one LWP is sufficient. However, an application that is I/O-intensive may require multiple LWPs to execute. Generally, an LWP is required for each concurrent blocking system call. For an example, that four different file-read requests occur simultaneously. Four LWPs are needed, because all could be waiting for I/O completion in the kernel. If a process has only three LWPs, then the fourth request must wait for one of the LWPs to return from the kernel.