This is a creation in Article, where the information may have evolved or changed.
Online a service has a serious problem, processing the number of messages 1k/s up, after viewing is blocked in a new function, this function is responsible for collecting information, sent to a channel, and then by a function, this processing function is very simple, see no problem, the biggest feature is to not lock, Only one goroutine.
The problem is obvious, only one goroutine, when the system is busy and there are a large number of goroutine, will not be dispatched, resulting in the collection function block, resulting in the number of message processing.
The dispatch is not dispatched, should not get the dispatch of the dispatch, and go runtime can not know that the goroutine should be dispatched, can only be fair dispatch, but the fair dispatch has caused the blockage!
This kind of problem is actually very common, not a goroutine problem! Even if you open multiple goroutine, you may still not get the dispatch! (Of course, in busy times, most of the time there is no such problem)
This article, "Remember once latency problem: Talk about Go's fair dispatch flaw" also talked about go this question, the author thinks the question has no solution.
In fact we can try, Golang provides a simpler way to runtime. Lockosthread ().
Official Introduction:
in this thread, and no other goroutine can.
The point is that no other Goroutine Can,lockosthread was originally designed for OpenGL and other things, but from the official note, we can use it to prioritize, lock a goroutine to a system thread, This thread only dispatches this goroutine, which can then be prioritized (relative to other goroutine). Because the system thread is scheduled based on the time slice, it allows the goroutine to get more time.
The following test shows the runtime. Lockosthread () can really affect scheduling and comment out runtime. Lockosthread (), there are 2-60 times the time difference.
Package Mainimport ("FMT" "OS" "Runtime" " Time") Func main () {varch = make (chanBOOL,20000) varbegin = Make (chanBOOL) go func () {runtime. Lockosthread ()<-begin FMT. Println ("begin") TM:=Time . Now () forI: =0; I <10000000; i++ { <-CH} fmt. Println (time. Now (). Sub (tm)) OS. Exit (0) }() forI: =0; I <50000; i++ { //Loadgo func () {varCountintLoad:=100000 for{Count++ifCount >=Load {count=0Runtime. Gosched ()}}} ()} forI: =0; I < -; i++{go func () { for{ch<-true}} ()} FMT. Println ("All start") Begin<-true Select {}}