I know there are three thread mapping model in operating system.
- One to One
- Many to One
- Many to Many
In this question I assume we use One to One model.
Let's say, right now I restart my computer, and there are 10 kernel-level threads already running.
After a while, I decide to run a python program which will launch one process with four threads. Three of the threads have to run a function that do a system call.
Here is a question, what is the correct scenario when I run the python program.
a) When a python program start, the kernel will launch another 4 threads in kernel space immediately (so there are 14 threads in kernel space now). When those 3 threads in user level initiate a system call, kernel will map those user-level threads to 3 of 4 kernel-level threads that kernel created when python program start, which also means we will waste 1 kernel-level thread.
b) When a python program start, the kernel will not launch another 4 threads in kernel space immediately. Instead, kernel will create new kernel-level threads whenever those 3 user-level thread initiate a system call and ready to talk with kernel. In this case kernel will just create 3 threads exactly, which also means we will not waste any kernel-level threads.
c) Very similar to second scenario, but in this case when those 3 user-level threads ready to run system call and talk with kernel, what kernel will do is make 3 of kernel-level threads that already created stop doing their current job, and then ask them to do the job that python program ask kernel do.
Which means the scheduler will pick up 3 random kernel-level threads to stop what they're doing, and then store those tasks information to somewhere. After that, scheduler will ask those 3 kernel-level thread to finish the python program job first. In this case we always have only 10 threads in kernel-level.
Any reply and suggested material to study is appreciated!
CodePudding user response:
Kernel threads are like a specialized task responsible for doing a specific operation (not meant to last long). They are not threads waiting for incoming request from user-land threads. Moreover, a system call does not systematically create a kernel thread (see this post for more information and this one for some context about system calls): a kernel thread is started when a background task is required like for dealing with IO requests for example (this post shows a good practical case though the description is a bit deep). Basic system calls just runs in the same user-thread but with higher privileges. Note the kernel functions use a dedicated kernel stack: each user-level thread has 2 stacks on Linux: one for user-land functions and one for kernel-land functions (for sake of security).
As a result, in practice, I think all answers are wrong in usual cases (ie. assuming the target operation do not require to create a kernel thread). If the target system calls done actually require to create kernel threads, then b) is the correct answer. Indeed, kernel threads are like a one-shot specialized task as previously stated. Creating/Destroying new kernel-threads is not much expensive since it is just basically a relatively lightweight task_struct
data structure internally.