After reading several sources I'm still confused about user- and kernel-level threads.
In particular:
Threads can exist at both the user level and the kernel level
What is the difference between the user level and kernel level?
After reading several sources I'm still confused about user- and kernel-level threads.
In particular:
Threads can exist at both the user level and the kernel level
What is the difference between the user level and kernel level?
One of the roles of a multitasking operating system kernel is scheduling: determining which thread of execution to execute when. So such a kernel has some notion of thread or process. A thread is a sequential piece of code that is executing, and has its own stack and sometimes other data. In an operating system context, people usually use process to mean a thread that has its own memory space, and thread to mean a thread that shares its memory space with other threads. A process can have one or more threads.
Some operating systems, for example older unix systems, only provide processes: every thread that the kernel manages has its own memory space. Other operating systems, for example most modern unix systems, allow processes to contain multiple threads of execution: they provide a kernel-level notion of threads.
It's also possible for a process to manage its own threading. In cooperative multithreading, the code of each thread contains instructions to switch to another thread. In preemptive multithreading, the process requests periodic asynchronous notifications from the kernel, and reacts to these notifications by switching to a different thread. This way, multithreading is implemented with no kernel cooperation, at the user level, in a library.
A system can offer both kernel-level and user-level threads; this is known as hybrid threading.
User- and kernel-level threads each have their benefits and downsides. Switching between user-level threads is often faster, because it doesn't require resetting memory protections to switch to the in-kernel scheduler and again to switch back to the process. This mostly matters for massively concurrent systems that use a large number of very short-lived threads, such as some high-level languages (Erlang in particular) and their green threads. User-level threads require less kernel support, which can make the kernel simpler. Kernel-level threads allow a thread to run while another thread in the same process is blocked in a system call; processes with user-level threads must take care not to make blocking system calls, as these block all the threads of the process. Kernel-level threads can run simultaneously on multiprocessor machines, which purely user-level threads cannot achieve.
Think of kernel level threads as "virtual processors" and user level threads as simply threads (Let's call them as such for now). Now, for a thread to be executed, it has get assigned on to a processor right? So, each thread gets assigned to a virtual processor so that it can be executed.
Here are facts
Creating a new virtual processor is a bit costly. (The kernel has to create an entry in Thread Control Block, assign stack etc.)
Creating a thread is pretty simple compared to creating a new virtual processor. An application developer can create threads using Thread Libraries provided by the programming languages and are managed in User Space. And different languages implement multithreading in different ways.
If threads are mapped onto a single virtual processor, then one must be careful not to make a blocking system call in any of the threads, because other threads can no more run concurrently.
This limitation can be overcome if a few more virtual processors can be created. Now, threads can run concurrently (in parallel if multiple real processors are present). A thread will not effect other threads which are mapped on other virtual processors.
In the latter model, either one or many threads can be mapped onto a virtual processors.
The above models are named Many to One, One to One and Many to Many respectively.
Referenes: Operating system concepts by Galvin et al. Topic: Threads -> Multithreading Models