[Reserved] Golang threading model you may not know

Original: Zhai succession (Cadogan) Senior Java, the beauty of Java Concurrency

I. Introduction

In this section we discuss Go threading model, first of all let's take a look back at three common thread model, then Go introduce unique threading model.

Two, three, threading model

Concurrent execution threads is an operating system to schedule, operating systems typically support thread in the kernel. And we created a thread in the use of high-level language programming time is user thread, the user threads and kernel threads that what is the relationship? In fact, the following three kinds of threading model to explain is that, depending on user threads and kernel threads and relations division.

2.1 one model

User threads and kernel threads in this thread model is one to one, when after starting from the entry point (for example, the main function), the operating system creates a process, where the main function of this thread is the main thread, the main function when we use in the high-level language to create a user thread, in fact corresponds to create a kernel thread, as shown below:

This advantage is threading model on a multiprocessor, a plurality of threads run in parallel can realize, and due to a network when a thread is blocked when the IO and other reasons, other threads are not affected.

The disadvantage is that due to the general operation of the system will limit the number of kernel threads, so the number of user threads will be limited. Further since the thread-one correspondence with the system user thread, such as thread when the user performs operation Io (system call), the need to switch from execution of the user program to the user mode kernel mode executes a kernel operation, and the like will be finished after the user mode to kernel mode switching execution of the user program, and this switching operation cost is relatively large.

In addition threading model here mention the next high-level language Java is this one of the model used, so the use of Java multi-threaded shared variables lock synchronization time can result in failure to obtain a lock thread context switching, and packet No JUC lock CAS operation is not generated a context switch.

2.2 Many-to-model

Many-to-model refers to a plurality of user threads corresponding to kernel threads, while only one user thread corresponding to a kernel thread, which corresponds to time with the plurality of user thread context switches a kernel thread of the thread is run by the user when the state library to do rather than by the operating system to do the scheduling system, which model is as follows:

This advantage is due to the model in user mode context switching, the switching speed is fast, low overhead; number of users can create additional threads may be many, restricted only by the memory size.

Since this model corresponding to a plurality of user threads kernel thread, the kernel thread corresponding to when a user thread is blocked when suspended, the kernel thread corresponding to the thread other users can not run, since this time has been blocked kernel threads hanging get up. Also, such a model can not make good use of the multi-core CPU to run concurrently.

2.3-many model

To-many model is a combination of features and many-to-one model, so that a large number of users corresponding to the thread of the few kernel threads, the model is as follows:

At this time each kernel thread corresponds to thread multiple users, each user has a thread can correspond to multiple kernel threads, when a user thread is blocked, which corresponds to the current kernel threads will be blocked, but blocked kernel threads corresponding other users can switch to another thread kernel threads continue to run so-many model can take full advantage of multi-core CPU to enhance performance efficacy.

In addition to-many model is also no limit to the number of threads the user, in theory, as long as enough memory to create unlimited.

Three, Go threading model

Go threading model belongs to the many-threaded model, the model follows

Go is used to use go goroutine statement creates a user may be considered a lightweight thread, the thread go model comprising three concepts: kernel thread (M), goroutine (G), the logical processor (P), each in Go logic processor (P) will be bound to one core thread, there is a local queue in each logical processor (P), used to store the assigned go goroutine runtime. In-many threading model described above is an operating system schedules threads running on physical CPU, in Go Go is scheduled to run when goroutine running on a logical processor (P).

Scheduling in the presence of two go, the operating system is a scheduling system, the scheduling system, the scheduling logic processor occupancy cpu time slice operation, a run-time scheduling system is to go, the scheduling system, the scheduling logic processing in a goroutine on the run.

After creating a goroutine go use statement is created goroutine go into the runtime global run queue in a scheduler, and the scheduler will assign goroutine global queue to a different logical processors (P) go running, goroutine assigned logical processor will be put (P) in the local queue, you can run on a logical processor when a local queue goroutine ready to be dispensed after the time slice after, as is currently being occupied by the logic of FIG. goroutine1 1 processor running.

需要注意的是为了避免某些goroutine出现饥饿现象,被分配到某一个逻辑处理器(P)上的多个goroutine是分时在该逻辑处理器运行的,而不是独占运行直到结束,比如每个goroutine从开始到运行结束需要10分钟,那么当前逻辑处理器下的goroutine1,goroutine2,goroutine3,并不是顺序执行,而是交叉并发运行的。

goroutine内部实现与在多个操作系统线程(Os 线程)之间复用的协程(coroutines)一样。如果一个goroutine阻塞OS线程,例如等待输入,则该OS线程对应的逻辑处理器P中的其他goroutine将迁移到其他OS线程,以便它们可以继续运行

如上图左侧假设goroutine1在执行文件文件读取操作,则goroutine1会导致内核线程1阻塞,这时候go运行时调度器会把goroutine1所在的逻辑处理器1迁移到其他的内核线程上(这里是内核线程2上),这时候逻辑处理器1上的goroutine2和goroutine3就不会受goroutine1的影响了。等goroutine1文件读取操作完成后goroutine1又会被go运行时调度系统重新放入到逻辑处理器1的本地队列。

需要注意的是go运行时内核线程(M)的数量默认是10000个,你可以使用runtime/debug包里面的debug.SetMaxThreads(10000)来设置。

默认情况下,Go默认是给每个可用的物理处理器都分配一个逻辑处理器(p),如果你需要修改逻辑处理器(P)个数可以使用runtime包的runtime.GOMAXPROCS函数设置.

至于goroutine(G)的数量则是由用户程序自己来确定,理论只要内存够大,可以无限制创建。

四、总结

本节我们探讨了go的线程模型,讲解了Go中是多对多的线程模型,正是由于这种线程模型才让go中每台机器可以创建成千上万的goroutine(轻量级线程),了解了go的线程模型,特别是其中的MPG概念,就可以随业务需要动态设置最优方案。

Guess you like

Origin www.cnblogs.com/yueshutong/p/11331862.html