What is the relation between kernel threading and user threading? - multithreading

I am learning the Computer OS, I am confused about the real relationship between kernel level threads and the user level thread, The staff just said they are mapped. I just wonder how they mapped, and what's that for?
Thank you.

Every code at some point executes at a kernel level thread. A user level thread can be thought of as an abstraction, they work as if they are kernel threads but it is up to the language or platform implementing those user threads to define how they're gonna work.
They might be mapped on a 1:1 basis to a kernel thread, but there might be a number of user threads sharing the same kernel thread (and in this case the platform/language that provides the user threads that takes care of switching between different user threads during the processor time given to the single kernel thread running them)

Related

one-to-one multi-threading model

In silberschatz "Operating System Concepts" book, section 4.3.2 says that
one-to-one model provides more concurrency than the many-to-one model
by allowing another thread to run when a thread makes a blocking
system call. It also allows multiple threads to run in parallel on
multiprocessors.
I have two questions here:
How can one thread be blocked and other mapped on kernel thread?
Dont we know that if one thread is blocked, entire process of that
user-level thread is blocked?
The OS considers user-level threads
as one thread only. It cant be assigned to multiple
processors/cores. Isn't the below given line contradicting that
idea?
It also allows multiple threads to run in parallel on
multiprocessors
Your understanding of user level threads and kernel level threads is not correct, in particular you need to understand how user level threads are mapped to kernel level threads. So first lets define some terms
Kernel thread
A thread (schedulable task) that is created and managed by the kernel. Every kernel level thread is represented by some data structure which contains information related to the thread. In the case of Linux it is task_struct. Kernel threads are the only threads that are considered by the CPU scheduler for scheduling.
Note : Kernel thread is a bit of misnomer as Linux kernel doesn't distinguish between a thread and a process, schedulable task would better describe this entity.
User thread
A thread that is created and managed by some library such as JVM above kernel level. The library that creates these threads is responsible for their management that is which thread runs and when.
User level to kernel level mapping
Now you can create as many user level threads as you want but to execute them you need to create some kernel level thread (task_struct). This creation of kernel level threads can be done in many ways
One to one model
In this case whenever you create a user level thread your library asks the kernel to create a new kernel level thread. In the case of Linux your library will use clone system call to create a kernel level thread.
Many to one model
In this case your library creates only one kernel level thread (task_struct). No matter how many user level threads you create they all share the same kernel level thread, much like the processes running on a single core CPU. The point to understand is that your library here acts much like the CPU scheduler, it schedules many user level threads on single kernel level thread.
Now to your question
The OS considers user-level threads as one thread only. It can’t be
assigned to multiple processors/cores. Isn't the below given line
contradicting that idea?
If you were using many to one model, in that case you will have only one kernel level thread for all of your user level threads and hence they cannot run on different CPU’s.
But if you are using a one to one model then each of your user level threads has a corresponding kernel level thread that can be scheduled individually and hence user level threads can run on different CPU’s given that you have more than one CPU.
You are suffering from a confusing book.
There are real threads (aka kernel threads, 1 to 1 model) and there are simulated threads (aka user threads, many to 1 model).
Some books make this more confusing by throwing a hypothetical many to many model.
User threads are obsolete. Any operating system book worth reading these days would treat them that way and describe them in historical terms.
How can one thread be blocked and other mapped on kernel thread? Dont we know that if one thread is blocked, entire process of that user-level thread is blocked?
You either have user threads or kernel thread. An application that did both would be royally screwed up.
The OS considers user-level threads as one thread only. It cant be assigned to multiple processors/cores. Isn't the below given line contradicting that idea?
In ye olde days a process was considered to be an execution stream and an address space. There were no threads. When threads became necessary (largely due to the need for Ada support), they were simulated using timers. The behavior of threads varied by operating system.
In Eunuchs variants, blocking calls block the process entirely. Thus in simulated (user) threads a blocking call in one thread would block all threads. This is not true on all operating systems.
Now, a process is one or more execution streams and an address space. That is what you ought be learning; not a bunch of technobabble.
A book that talks about threads in terms of 1-to-1 or many-to-1 models is only fit to line cat boxes.

Differences between Multi-threading Models

Many-to-One Model
One-to-One Model
Many-to-Many Model
Advantages and disadvantages of each model ?
Can you give an example ?
EDIT:
One thing is confusing me with the Many-to-One Model
I'm quoting the book:
"Thread management is done by the thread library in user space, so it
is efficient; but the entire process will block if a thread makes a
blocking system call. Also, because only one thread can access the
kernel at a time, multiple threads are unable to run in parallel on
multiprocessors"
Does it mean all processes in kernel will be blocked, due to the fact that the swapping is done by the application, not by OS scheduler.
(since in this model we manage threads in user-mode) ?
Or, only the threads belonging to the same process of the thread that made the blocking system call will be blocked ?
Thanks in advance!
We have to assign user level threads to kernel level threads, based on the this the mapping can be:
One to one (One user thread mapped to one kernel level thread)
Many to one(Many User level threads mapped to one kernel level thread)
Many to many(Many User level threads mapped to many kernel level threads)
Here the number of kernel level threads are generally set to lesser than number of user level thread, since management of kernel level threads is much more expensive since it involves kernel intervention in their(kernel level thread's) management.
Because of this reason only the fourth mapping of "one to many"(one user level thread to multiple kernel level threads) to one does not make sense.
"Thread management is done by the thread library in user space, so it is efficient; but the entire process will block if a thread makes a blocking system call. Also, because only one thread can access the kernel at a time, multiple threads are unable to run in parallel on multiprocessors"
this example may help to understand this line:
Does it mean all processes in kernel will be blocked, due to the fact that the swapping is done by the application, not by OS scheduler. (since in this model we manage threads in user-mode) ? Or, only the threads belonging to the same process of the thread that made the blocking system call will be blocked ?
One process's threads are independent of other process's threads.So only the threads belonging to the same process of the thread that made the blocking system call will be blocked.
I hope this does make sense to you...
I can see your problem. You have a horrible book.
You're asking about a couple of related issues. First of all, there are two general ways to implement threads.
1) Threads are implemented in a library using timers. In systems that schedule processes for execution this is the only way to do thread. This was ONLY way to do threads in the olde days. This system is usually called "user threads." User threads are multiplexed within a process. The process does the scheduling of its own threads.
The mythical advantage of "user threads" over "kernel threads" (below) is that they are more efficient. This is what your quoted passage is referring to. The statement "the entire process will block if a thread makes a blocking system call" is only true on some [unix] systems.
2) Threads are implemented in the operating system. A process consists of an address space and one or more threads. The operating system kernel schedules THREADS for execution rather than PROCESSES. These are kernel thread.
Note that even if the system supports kernel threads, it is possible for a process to use user threads. The two are not mutually exclusive. However, a system that does not natively support kernel threads can only use user thread.
That's the simple way to explain the different threading models.
-=-=-=-=-=-=-=-=-=-=-=-
The one-to-one, many-to-one, and many-to-many models are a needless confusion for students. Now we have to get into overlapping terminology.
Let's change the terminology around. For #1, instead of calling the schedulable unit of execution a "process" we call it a "kernel thread." There can only be one kernel thread per process in this model. Then the threads in the process are are "user threads." Any number of user threads execute within/are mapped to a kernel thread. This is then the many-to-one model. User threads = many-to-one.
If we have the operating system create the thread (a kernel thread), let's theoretically call what is being executed a "user thread." Each user thread maps to/executed in one and only one kernel thread. This is then the one-to-one model.
The many-to-one model is the same as what is normally called "user threading model."
The terminology is starting to get nonsensical because there is only one thread but we are calling it a user thread mapped to a kernel thread.
The one-to-one model is what is normally called the kernel threading model.
Lastly, we get to the many-to-many model. It is theoretical BS. In theory, there could be many user threads mapped to many kernel threads. In other words, a single user thread could execute within different kernel threads. I have never heard of system implementing threads this way and I cannot imagine any practicable advantage of such a system.
-=-=-=-=-=-=-=-=-=-=-=-=-
As to your last question, in some operating systems, blocking system calls block also block the timers used to implement user threads (a/k/a many-to-one). If one thread make blocking call, it blocks all the other threads in the PROCESS from executing until the blocking call completes.
This blocking does not occur in all systems (something an OS textbook should point out).

Mapping User-level threads and Kernel-level threads

How are User-level threads mapped to Kernel-level threads?
It varies by implementation. The three most common threading models are:
1-to-1: Each user-level thread has a corresponding entity that is scheduled by the kernel.
n-to-1: Each process is scheduled by the kernel. Thread scheduling takes place entirely in user space.
n-to-m: Each process has a pool of entities that are scheduled by the kernel. These are assigned to run particular user-level threads by a user-space scheduler that is part of the process.
Modern implementations are almost all 1-to-1.
There's a bit of confusion about the terminology used for referring to ULTs and KLTs.
Following are the two different interpretations. Please correct me if I got this wrong:
KLTs are needed to achieve concurrency in the kernel (Note the interpretation of Kernel as a Process or a live entity). This is true about Micro kernels like Symbian, where a kernel thread is responsible for every hardware resource of the system (e.g File Server, Location Server, Calendar Server, etc). However, in a kernel like Linux, which is mostly a library (and not a process or a living entity on its own), there's really no meaning for Kernel threads. In Linux, every thread you create is treated by the Kernel as a process and Kernel always runs either in the Process context or the Interrupt context.
Second interpretation is based on whether Threading (or concurrency) is visible to the Kernel or not. For instance, using setjmp, longjmp one can achieve concurrency at user space. Like already discussed, Kernel is totally unaware of this. This concurrency may be termed as ULT. And the thread whose creation the Kernel is aware of (one using Clone() system call) may be called KLT.

Threads: Why must all user threads be mapped to a kernel thread?

So two questions here really. First, (and yes, I have searched this already, but wanted clarification), what is the difference between a user thread and a kernel thread? Is it simply that one is generated by a user program and the other by an OS, with the latter having access to privileged instructions? Are they conceptually the same or are there actual differences in the threads themselves?
Second, and the real problem of my question is: the book I am using says that "a relationship must exist between user threads and kernel threads," going on to list the different models of such a relationship. But the book fails to clearly explain why a user thread must always be mapped to a specific kernel thread. Why is this?
A kernel thread is a thread object maintained by the operating system. It is an actual thread that is capable of being scheduled and executed by the processor. Typically, kernel threads are heavyweight objects with permissions settings, priorities, etc. The kernel thread scheduler is in charge of scheduling kernel threads.
User programs can make their own thread schedulers too. They can make their own "threads" and simulate context-switches to switch between them. However, these threads aren't kernel threads. Each user thread can't actually run on its own, and the only way for a user thread to run is if a kernel thread is actually told to execute the code contained in a user thread. That said, user threads have major advantages over kernel threads. They can be a lot more lightweight, since they don't necessarily need to have their own priorities, can be managed by a single process (which might have better info about what threads need to run when), and don't create lots of kernel objects for purposes of security and locking.
The reason that user threads have to be associated with kernel threads is that by itself a user thread is just a bunch of data in a user program. Kernel threads are the real threads in the system, so for a user thread to make progress the user program has to have its scheduler take a user thread and then run it on a kernel thread. The mapping between user threads and kernel threads doesn't have to be one-to-one (1 : 1); you can have multiple user threads share the same kernel thread (only one of those user threads runs at a time), and you can have a single user thread which is rotated across different kernel threads in a 1 : n mapping.
I think a real world example will clear the confusion, so let’s see how things are done in Linux.
First of all Linux doesn’t differentiate between process and thread, entity that can be scheduled is called task in Linux and represented by task_struct. So whenever you execute a fork() system call, a new task_struct is created which holds data (or pointer) associated with new task.
So in Linux world a kernel thread means a task_struct object.
Because scheduler only knows about these entities which can be assigned to different CPU’s (logical or physical). In other words if you want Linux scheduler to schedule your process you must create a task_struct.
User thread is something that is supported and managed outside of kernel by some execution environment (EE from now on) such as JVM. These EE’s will provide you with some functions to create new threads.
But why a user thread must always be mapped to a specific kernel thread.
Let’s say you created some threads using your EE. eventually they must be executed by the CPU and from above explanation we know that the thread must have a task_struct in order to be assigned to some CPU. That is why the mapping must exist. It’s the duty of your EE to create task_structs.
If your EE uses many to one model then it will create only one task_struct for all the threads and it will schedule all these threads onto that task_struct. Think of it as there is one CPU (task_struct) and many processes (threads created in EE), your operating system (the EE) will multiplex these processes on that single CPU.
If it uses one to one model than there will be one task_struct for every thread created in EE. So when you create a new thread in your EE, corresponding task_struct gets created in the kernel.
Windows does things differentlly ( process and thread is different ) but general idea stays the same that is kernel thread is the entity that CPU scheduler considers for assignment hence user threads must be mapped to corresponding kernel threads (if you want CPU to execute them).

What is the difference between kernel threads and user threads?

What is the difference between kernel threads and user threads? Is it that kernel thread are scheduled and executed in kernel mode? What are techniques used for creating kernel threads?
Is it that user thread is scheduled, executed in user mode? Is it that Kernel does not participate in executing/scheduling user threads? When interrupts occur in executing user thread then who handles it?
Whenever, thread is created a TCB is created for each. now in case of user level threads
Is it that this TCB is created in user's address space ?
In case of switching between two user level threads who handles the context switching ?
There is a concept of multithreading models :
Many to one
One to one
Many to Many.
What are these models? How are these models practically used?
Have read few articles on this topic but still confused
Wants to clear the concept ..
Thanks in advance,
Tazim
Wikipedia has answers to most if not all of these questions.
http://en.wikipedia.org/wiki/Thread_(computer_science)
http://en.wikipedia.org/wiki/Thread_(computer_science)#Processes.2C_kernel_threads.2C_user_threads.2C_and_fibers
What is the difference between kernel threads and user threads?
Kernel threads are privileged and can access things off-limits to user mode threads. Take a look at "Ring (Computer Security)" on Wikipedia. On Windows, user mode corresponds to Ring 3, while kernel mode corresponds to Ring 0.
What are techniques used for creating kernel threads?
This is extremely dependent upon the operating system.
now in case of user level threads Is it that this TCB is created in user's address space ?
The TCB records information about a thread that the kernel uses in running that thread, right? So if it were allocated in user space, the user mode thread could modify or corrupt it, which doesn't seem like a very good idea. So, don't you suppose it's created in kernel space?
What are these models? How are these models practically used?
Wikipedia seems really clear about that.
Kernel thread means a thread that the kernel is responsible for scheduling. This means, among other things, that the kernel is able to schedule each thread on different cpus/cores at the same time.
How to use them varies a lot with programming languages and threading APIs, but as a simple illustration,
void task_a();
void task_b();
int main() {
new_thread(task_a);
new_thread(task_b);
// possibly do something else in the main thread
// wait for the threads to complete their work
}
In every implementation I am familiar with, the kernel may pause them at any time. ("pre-emptive")
User threads, or "User scheduled threads", make the program itself responsible for switching between them. There are many ways of doing this and correspondingly there is a variety of names for them.
On one end you have "Green threads"; basically trying to do the same thing as kernel threads do. Thus you keep all the complications of programming with real threads.
On the opposite end, you have "Fibers", which are required to yield before any other fiber gets run. This means
The fibers are run sequentially. There is no parallell performance gains to be had.
The interactions between fibers is very well defined. Other code run only at the exact points you yield. Other code won't be changing variables while you're working on them.
Most of the low-level complexities programmers struggle with in multithreading, such as cache coherency (looking at MT questions on this site, most people don't get that), are not a factor.
As the simplest example of fibers I can think of:
while(tasks_not_done) {
do_part_of_a();
do_part_of_b();
}
where each does some work, then returns when that part is done. Note that these are done sequentially in the same "hardware thread" meaning you do not get a performance increase from parallellism. On the other hand, interactions between them are very well defined, so you don't have race conditions. The actual working of each function can vary. They could also be "user thread objects" from some vector/array.
Essentially user threads run in the context of a user with the appropriate privilege levels e.g. user threads most certainly won't have access to kernel-level memory/data structures/routines etc. Whereas Kernel threads run in the context of the OS kernel thus giving them privileges to execute code which has access to low level kernel routines/memory/data structures.

Resources