In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article shows you how one of the endless loops in Go when a single-core CPU opens two Goroutines. The content is concise and easy to understand. It will definitely make your eyes shine. I hope you can gain something through the detailed introduction of this article.
Today's hero, is with Go engineers have scheduling related knowledge, that is,"single-core CPU, open two Goroutines, one of which endless loop, what will happen?" "
Please recite the answer in your mind here, and then go to discuss a wave of Go technical philosophy with fried fish.
problem definition
To solve this problem, we need to split the problem and see that it has the following elements:
The computer running Go has only a single CPU. Two goroutines are running. A Goroutine endless loop.
According to the meaning of this question, it can be roughly understood that what it wants to ask is some knowledge understanding related to Go scheduling.
single-core CPU
The first point is to make clear what effect the variable definition of "computer has only one single-core CPU" will have on Go program, otherwise it will be difficult to continue to expand.
Since Goroutine is explicitly involved, this will examine your basic understanding of Go's scheduling model GMP.
From a single-core CPU point of view, the biggest impact is P in the GMP model, because the number of P is consistent with the CPU core number (GOMAXPROCS) by default.
G: Goroutine, actually every time we call go func we generate a G. P: Processor, processor, the number of P is generally the number of cores of the processor, which can be modified through GOMAXPROCS. M: Machine, system thread.
These interactions are actually derived from Go's M: N scheduling model. That is, M must bind to P, and then loop over M to find a workable G to perform the corresponding task.
Goroutine Limited
The second point is that the number and mode of operation of Goroutine are limited. There are two Goroutines, one Goroutine in a loop and the other in normal operation.
This can be understood as Main Goroutine + starting a new Goroutine running endless loop, because the main function itself is a main coroutine running, no problem.
It should be noted that Goroutine runs an endless loop, that is,"business logic" runs all the time. This block needs to be associated with a single-core CPU, considering whether it will always block and run the entire Go process to hang?
Note: But if you are interviewing on the spot, you can enumerate this scene first and explain it clearly. Ask the interviewer if this is the case.
Go version of the problem
The third point is an implicit extension point. If you're an older Go fan and keep an eye on updates to Go versions (at least big ones), you should know that Go's scheduling is subject to change (as explained in a later section).
Therefore, the problem in this article may have different results in different versions of Go. However, the interviewer did not point out that it is necessary to consider:
The interviewer deliberately does not point out, waiting for you to point out. The interviewer didn't notice this, didn't think so much. The interviewer himself does not know this piece of "new" knowledge, and his knowledge may still be old.
If you notice, it's a small bright spot, indicating that you have some accumulated knowledge in this area.
actual combat drills
In the last three seconds, you've gone through all of the above considerations in your head. Next, we formally entered the actual combat exercise and constructed an example:
// Main Goroutine
func main() {
//Analog single-core CPU
runtime.GOMAXPROCS(1)
//Simulate Goroutine loop
go func() {
for {
}
}()
time.Sleep(time.Millisecond)
fmt.Println("brain fried fish")
}
In the example above, we achieved the goal of the interview question by:
The set runtime.GOMAXPROCS method simulates a scenario where there is only one P on a single CPU. Run a Goroutine, internally run a for endless loop, to achieve the purpose of blocking the run. Running a Goroutine, the main function is itself a Main Goroutine.
Think about it: does this program output "brain fried fish" and why?
The answer is:
No results will be output until Go1.14. After Go1.14 and later, the output results can be normal. why
What's going on here, what are the causes and criteria for these two situations, and what are the effects of changes to the Go version?
No results will be output
Obviously, this program has a Goroutine that is executing an endless loop, which means it must not be preempted.
There are no calls to relinquish execution (runtime.Gosched) or other calls that might cause execution to shift. Therefore, Goroutine has no chance to slip away and can only work all the time...
Why does the Main Goroutine fail to run? In fact, the reason is that sleep will be called first, but because of the single-core CPU, it only has a unique P. The only P has been working and unwilling to leave work (execution for endless loop, forced to work indefinitely).
Therefore, the main coroutine never has a chance to schedule, so the Go program naturally blocks in the Goroutine that executes the endless loop, and can never get off work (after execution, exit the program).
normal output result
So why does Go 1.14 and later output normally again?
It is mainly in Go1.14 that signal-based preemptive scheduling is implemented to solve some of the above scenarios that still cannot be preempted.
The main principle is that Go programs, when started, register in the runtime. sieghandler method and bind SIGURG signals:
func mstartm0() {
...
initsig(false)
}
func initsig(preinit bool) {
for i := uint32(0); i < _NSIG; i++ {
...
setsig(i, funcPC(sighandler))
}
}
Bind the corresponding runtime.doSigPreempt method:
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
...
if sig == sigPreempt && debug.asyncpreemptoff == 0 {
//execute preemption
doSigPreempt(gp, c)
}
}
Meanwhile, the runtime.sysmon method of the scheduler calls the restore method to handle two scenarios:
Preemption blocks P on system calls. Preemption of G running too long.
The method detects P that fits the scenario and sends a signal to M when one of the two scenarios is met. M will sleep the blocking Goroutine after receiving the signal, call the bound signal method, and reschedule. To solve this problem.
Note: In Go, sysmon is used to detect preemption. sysmon is Go's Runtime system detector, sysmon can perform a series of actions such as forcec, netpoll, and retrieve (via @xiaorui).
In this article, we aim at "single-core CPU, open two Goroutines, one of which is endless loop, what happens?" "The problem was analysed.
The logic of different programs takes different forms for different versions of Go, but the underlying principles are related to Go scheduling model and preemption.
The above is what happens when a single-core CPU opens two Goroutines in Go and one of them is an endless loop. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserves, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.