In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "analyzing Go collaboration and preemption". In daily operation, I believe many people have doubts in analyzing Go collaboration and preemption. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "analyzing Go collaboration and preemption"! Next, please follow the editor to study!
Collaborative scheduling
Active user concession: Gosched
Gosched is a means of actively giving up execution, and the user state code transfers the execution opportunity by calling this interface, so that other "people" can also get the chance to be scheduled in the intensive execution process.
The implementation of Gosched is very simple:
/ / Gosched will give up the current P and allow other Goroutine to run. / / it does not delay the current Goroutine, so execution is automatically restored func Gosched () {checkTimeouts () mcall (gosched_m)} / / Gosched continues to execute func gosched_m (gp * g) {on g0. GoschedImpl (gp)}
It first notifies the Goroutine waiting to be ready through the note mechanism:
/ / checkTimeouts restores those Goroutine that are waiting for a note whose deadline has been triggered. Func checkTimeouts () {now: = nanotime () for n, nt: = range notesWithTimeout {if n.key = = note_cleared & & now > nt.deadline {n.key = note_timeout goready (nt.gp, 1)}} func goready (gp * g, traceskip int) {systemstack (func () {ready (gp, traceskip, true)})} / / Mark gp as ready to run func ready (gp * g, traceskip int) Next bool) {if trace.enabled {traceGoUnpark (gp, traceskip)} status: = readgstatus (gp) / / marked as runnable. _ g _: = getg () _ glock.m.locksblocks + / / forbids preemption Because it can save p if status& ^ _ Gscan! = _ Gwaiting {dumpgstatus (gp) throw ("bad g-> status in ready")} / / as Gwaiting or Gscanwaiting in the local variable, mark Grunnable and put it in the run queue runq casgstatus (gp, _ Gwaiting, _ Grunnable) runqput (_ g_.m.p.ptr (), gp) Next) if atomic.Load (& sched.npidle)! = 0 & & atomic.Load (& sched.nmspinning) = = 0 {wakep ()} _ glock.m.locksmurt-if _ g_.m.locks = = 0 & & _ g_.preempt {/ / resume preemption request _ g_.stackguard0 = stackPreempt}} func notetsleepg (n * note, ns int64) bool {gp: = getg () if it has been cleared in newstack. If ns > = 0 {deadline: = nanotime () + ns... NotesWithTimeout [n] = noteWithTimeout {gp: gp, deadline: deadline}. Gopark (nil, nil, waitReasonSleep, traceEvNone, 1)... Delete (notesWithTimeout, n).}.}
Then call gosched_m through mcall to continue execution on G0 and give up P, which essentially causes G to give up its current execution right on M, M to execute other G, and put itself into the global queue for subsequent scheduling when the context is switched:
Func goschedImpl (gp * g) {/ / discard the current g running status status: = readgstatus (gp). Casgstatus (gp, _ Grunning, _ Grunnable) / / causes the current m to abandon g dropg () / / and put g back into the global queue lock (& sched.lock) globrunqput (gp) unlock (& sched.lock) / / re-enter the scheduling cycle schedule ()}
Of course, although it has the ability to actively abstain, it is more demanding of users of the Go language, because users need to identify whether they need to give up time slices when writing concurrent logic, which is not user-friendly, and many new Go users will not be aware of this problem, which we will discuss further in the subsequent preemptive scheduling.
Active scheduling waiver: stack expansion and preemption marking
Another way to give up actively is achieved by preempting the tag. The basic idea is to insert a preemption detection instruction in the preface of each function call, and when it is detected that the current Goroutine is marked as preemptive, it will actively interrupt execution and relinquish the right of execution. On the surface, the idea looks simple, but it is more complicated to implement.
As we have learned in section 6.6 implementing stack management [2], the preface of the function call checks the size between the SP register and the stackguard0, and if the SP is less than stackguard0, it triggers the morestack_noctxt and triggers the stack segmentation operation. In other words, if the preemption flag sets stackgard0 to be larger than all possible SP (that is, stackPreempt), morestack is triggered, which in turn invokes newstack:
/ / Goroutine preemptive request / / Storage to g.stackguard0 to cause stack segment check failure / / must be larger than any actual SP / / hexadecimal is: 0xfffffade const stackPreempt = (1
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.