The problem

(1) What are the thread types?

(2) What are thread models?

(3) Which thread model does each language use?

Introduction to the

In Java, we usually talk about concurrent programming, multi-threading, sharing resources and other concepts are related to threads. The threads mentioned here should actually be called “user threads”, and corresponding to the operating system, there is another thread called “kernel threads”.

The user thread is located on the kernel and its management does not require kernel support. Kernel threads are directly supported and managed by the operating system. Almost all modern operating systems, including Windows, Linux, Mac OS X, and Solaris, support kernel threads.

Ultimately, there must be some kind of relationship between the user thread and the kernel thread, and in this chapter we’ll look at three common approaches to establishing this relationship: many-to-one, one-to-one, and many-to-many.

Many-to-one model

Many-to-one thread model, also known as user-level thread model, means that multiple user threads correspond to the same kernel thread, and all the details of thread creation, scheduling and synchronization are handled by the process’s user-space thread library.

Advantages:

  • Many operations of the user thread are transparent to the kernel, and there is no need for frequent switching between user mode and kernel mode, which makes the creation, scheduling and synchronization of the thread very fast.

Disadvantages:

  • Since multiple user threads correspond to the same kernel thread, if one of the user threads blocks, the other user threads cannot execute.
  • The kernel does not know which threads exist in the user mode, so it cannot achieve complete scheduling and priority like the kernel thread.

Many languages implement coroutines that are essentially this way, such as Python’s GEvent.

One-to-one model

One-to-one model, also known as kernel-level threading model, that is, one user thread corresponds to one kernel thread, and the kernel is responsible for the scheduling of each thread, which can be scheduled to other processors.

Advantages:

  • Simple implementation [this article by the public number “Tong Elder brother read source code” original];

Disadvantages:

  • Most operations on the user thread will be mapped to the kernel thread, causing frequent switching between the user and kernel states.
  • The kernel maps scheduling entities for each thread. If a large number of threads appear in the system, the system performance will be affected.

Java uses a one-to-one threading model, so be careful about starting a thread in Java.

Many-to-many model

Many-to-many model, also known as the two-level threading model, is the product of learning from others, fully absorbing the advantages of the first two threading models and trying to avoid their disadvantages.

In this model, user threads and kernel threads are mapped many-to-many (m: n, usually m>=n).

First, unlike the many-to-one model, a process in the many-to-many model can be associated with multiple kernel threads, so multiple user threads in the process can be bound to different kernel threads, which is similar to the one-to-one model.

Second, different from the one-to-one model, all users of the thread is not in its process and the kernel thread binding, but can be dynamically bound kernel threads, when a kernel thread because its binding user thread blocking operation is the kernel yield the CPU scheduling, the rest of the process of its associated user threads can again with other kernel threads run binding.

Many-to-many model, therefore, is not much of a model that completely on your own schedule is not completely on the one-to-one model of operating system scheduling, but the intermediate state (work) own scheduling and dispatch system, because of the high complexity of the model, the operating system kernel developers generally will not use, so more time as the form of a third-party library.

Advantages:

  • Light weight with many-to-one model;
  • Since there are multiple kernel threads, if one user thread blocks, the other user threads can still execute.
  • Due to the corresponding multiple kernel threads, it can achieve more complete scheduling, priority, etc.

Disadvantages:

  • Implementation of complex [this article by the public number “Tong Elder brother read source code” original];

The Goroutine scheduler in Go is implemented in this way. In Go, a process can launch thousands of Goroutines, which is an important reason for its “high concurrency” aura since its inception.

When we look at ForkJoinPool in Java, we will compare it with the PMG threading model of Go.

conclusion

(1) Threads are divided into user threads and kernel threads;

(2) Thread model has many-to-one model, one-to-one model and many-to-many model;

(3) The operating system generally only realizes one-to-one model;

(4) Java uses a one-to-one thread model, so its one thread corresponds to one kernel thread, and scheduling is entirely handled by the operating system;

(5) Go uses a multi-threaded threaded model, which is very similar to that of ForkJoinPool in Java.

(6) Python’s GEvent uses a many-to-one thread model;

eggs

What thread model do the languages you’ve studied use?

Recommended reading

1, Dead Knock Java collection series

Deadknock Java atom series

3, Deadknock Java synchronization series

Welcome to pay attention to my public number “Tong Elder brother read source code”, view more source code series articles, with Tong elder brother tour the ocean of source code.