This post is a complement to the previous blog post and is intended to fill in the blanks on user-level and kernel-level threads. Hopefully the reader will have a better understanding of threads.

Xiao Bai is learning multithreaded programming recently.

The information about multithreading on the net is very much, small white soon understood the basic concept of thread, but about “user level thread and kernel level thread” concept, she however how also do not know clearly, had to consult xiao Ming of solid foundation of operating system.

For Xiao Bai’s question, Xiao Ming always patiently answer: “Thread inside these two concepts are really difficult to understand, I first tell you about the user level thread.”

User-level thread

“Since you say you’ve seen the basic concept of threads, I’ll skip this section.

The concept of threads was invented a long time ago, but operating system vendors couldn’t just change the kernel of an operating system because stability was Paramount to them. What if something goes wrong by adding something unverified to the kernel? So if you want to verify the availability of threads, you have to find another way.”

“I know, I know, the researchers wrote a library of functions for threads, and used the library to implement threads! Small white complacently say: “this I just saw on the net.”

“Yes, they put thread creation, thread termination, etc. functions in the thread library, and the user can call these functions to implement the desired functions.” Ming took a piece of paper and wrote down some functions: pthread_creat, pthread_exit, pthread_join, and pthread_yield. Then he said, “These are some important functions. You should be able to guess their functions, right?”

“Emmmm, let’s see, pthread_creat is to create a new thread, pthread_exit is to end a thread, pthread_join is, I guess, to prepare a thread and add it to the ready queue. I don’t know about that last function.”

“It doesn’t matter if you don’t know. You’ll see.” Ming continued: “Remember, the thread library we just said is located in user space, the operating system kernel knows nothing about this library, so from the kernel point of view, it is still managed in the normal way.”

Xiao Bai asked: “So the operating system still only sees processes? So a multithreaded process that I wrote with a thread library can only run on one CPU core at a time?”

Xiao Ming nodded and said: “You’re right, this is A disadvantage of the user-level threads and the threads can only take up A nuclear, so do the parallel acceleration, and because the user thread for transparency, the operating system can’t take the initiative to switch threads, in other words, if A, B is the same process of two threads, A running, If thread B wants to run, it will have to wait for THREAD A to abandon the CPU by calling the pthread_yield function.”

Tobe Note: User-level threads are invisible to the operating system, also known as transparency.

“Stop and let me think,” Haku thought quickly over Ming’s words. “Does this mean that even with thread libraries, user-level threads can’t do the same rotation scheduling as processes?”

“Quite right! You seem to have a pretty good idea of what a process is. However, while you can’t do rotation scheduling, user-level threads have their own advantages — you can customize the scheduling algorithm for your application, and it’s up to you when to exit the thread. As I said, since the operating system only sees processes, what do you think happens if a thread blocks?”

“In the view of the operating system, if a process is blocked, then the entire process is blocked and cannot get CPU resources until the blocking operation is complete. That’s like, all the threads are blocked.” Small white satisfied answer.

“Right, so if you let the thread block, the efficiency of the process will be greatly affected, so in this process, an alternative emerged — jacket. By jacket, you turn a blocking system call into a non-blocking system call.”

Small white surprised to ask: “How can this be done? Can a blocked call become unblocked?”

Xiaoming replied: “Let me take an example. Instead of calling a system I/O routine directly, call an application-level I/O jacket routine. The code in this jacket routine checks and determines if the I/O device is busy, and if so, blocks the thread in user mode. Then hand control to another thread. Check the I/O device again at regular intervals. As you said, the blocking call will still be executed eventually, but using jacket can shorten the blocking time. Depending on the implementation, however, there may be cases where it is not blocked.”

Ming paused for a moment and said, “So much for user-level threads. Let’s talk about kernel-level threads.”

Kernel level thread

“Kernel-level threads are much easier to talk about with user-level threads in the background. We now know that many operating systems already support kernel-level threads. To implement threads, the kernel needs to have a thread table that keeps track of all the threads in the system. When a new thread needs to be created, a system call is made and the thread table is updated by the operating system. Of course, there are still traditional schedules. What do you think would be good if the operating system could “see” threads? “

Xiao Bai confidently answered: “If the operating system kernel knows the existence of threads, it can be like scheduling multiple processes, put these threads on several CPU cores, can achieve the actual parallel.”

“Another thing you didn’t mention is that if thread A is visible, then if thread A is blocked, the other thread belonging to the same process will not be blocked. This is the absolute advantage of kernel-level threads.”

“Don’t kernel-level threads have any disadvantages?”

“There are drawbacks, of course. If you think about it, having an operating system schedule threads means that every time you switch threads, you have to ‘get stuck’ in kernel mode, and switching from user mode to kernel mode is expensive, so kernel-level thread switching is more expensive than user-level thread switching. It is also important to note that thread tables are stored in a fixed table space or stack space of the operating system, so the number of kernel-level threads is limited and cannot scale as well as user-level threads.”

“That’s it for kernel-level threads, and I’ll leave you with a picture at the end, and if you can understand it, you’ve understood the concept of the day.”

Small white complacently say: “I certainly read understand, thank small bright!”

I hope you have learned something after reading my article.

Thanks for reading and we’ll see you soon!

Disclaimer: Original article, unauthorized reprint prohibited