The article continues to update, you can wechat search a “Golang white growth” first time to read, reply to [tutorial] get golang free video tutorial. This article is available at GitHub github.com/xiaobaiTech… Welcome Star.

What is the GM model

Prior to Go 1.1, this was the GM model.

  • G, coroutine. Usually in code, a method is executed using the go keyword, which equals a G.

  • M, kernel thread, operating system kernel can’t see G and P, only know that it is executing a thread. G and P are both implementations at the user level.

In addition to G and M, there is also a global coroutine queue, which holds multiple gs in a running state. If M wants to get G, it needs to access a global queue. At the same time, the kernel thread M can exist more than one at the same time, so concurrency security needs to be considered when accessing. So the global queue has a global lock that needs to be acquired on every access.

It’s fine when the concurrency is small, but when the concurrency is large, this lock becomes a performance bottleneck.

What is the GMP model

Based on the idea that nothing can be solved by adding an intermediate layer, Golang added a scheduler P on the basis of the original GM model, which can be simply understood as adding an intermediate layer between G and M.

Hence the present GMP model.

  • The addition of P also brings a local coroutine queue, similar to the global queue mentioned above, which is also used to store G. If you want to obtain G waiting to run, you will preferentially get it from the local queue, and access to the local queue does not need to lock. The global coroutine queue still exists, but its function is weakened, and it will not get G in the global queue until it is absolutely necessary.

  • In the GM model, M wants to run G, just go to the global queue and get it; In the GMP model, in order for M to run G, it must first fetch P and then G from the local queue of P.

  • When G is created, the new G is preferentially added to the local queue of P. If the local queue is full, half of the G in the local queue is moved to the global queue.

  • When the local queue of P is empty, it is fetched from the global queue.

  • If the global queue is empty,MFrom the otherPLocal queue ofStealing half GOn yourPLocal queue of.

  • MrunG.GAfter execution,MfromPGet the next oneG“And so on.

Why doesn’t the logic of P just add to M

This is mainly because M is actually a kernel thread, the kernel only knows that it is running threads, and golang’s runtime (scheduling, garbage collection, etc.) is actually user-space logic. Where does the operating system kernel know, nor does it need to know that there are so many golang apps in user space. All this logic to the application layer to do, after all, it is not appropriate to change the kernel thread logic.

If the article helps you, look at the bottom right corner of the article and do something positive (click twice) to support it. (Crazy hint, come on, this is really important to me!)

I’m Xiao Bai, and I’ll see you next time.

The resources

[1] “Golang Scheduler GMP Principle and Scheduling Full Analysis” — Aceld

[2] Why should GMP Model have P — Fried fish

[3] Scheduler in Depth on Go — Qcrao

Article recommendation:

  • Shame on everyone. After three years of golang, I still can’t get this memory leak question right
  • Hardcore! HTTP interview questions
  • Programmer’s Guide to Preventing sudden death
  • Stick the TCP packet packets: I just made mistakes every packet | hardcore diagram
  • Hardcore illustration! 30 pictures take you to understand! What’s the difference between a router, a hub, a switch, a bridge, and an optical modem?

Don’t say that, pay attention to the public number: [Golang white growth record], together in the ocean of knowledge choke water