go routine blocking the others one [duplicate]

大城市里の小女人 提交于 2019-11-27 03:50:40

问题


The following code run forever instead of stopping one second after the beginning. The go routine with the infinite loop seems to prevent the other one from sending to the timeout channel. Is that normal ?

 func main(){
   timeout:=make(chan int)
   go func(){
      time.SLeep(time.Second)
      timeout<-1
    }()

    res:=make(chan int)
    go func(){
        for{
        }
        res<-1
    }()
    select{
        case<-timeout:
            fmt.Println("timeout")
        case<-res:
            fmt.Println("res")
    }
}

回答1:


Short answer: yes.

The current implementation uses cooperative scheduling among goroutines. This means that a goroutine must hand off execution to the scheduler for another goroutine to run. There is hope in the future to use a preemptive scheduler which will not have this limitation.

Goroutines yield to the scheduler when any of the following happens (may not be a comprehensive list):

  • unbuffered chan send/recv
  • syscalls (includes file/network reads and writes)
  • memory allocation
  • time.Sleep() is called
  • runtime.Gosched() is called

The last one allows you to manually yield to the scheduler when you have a very processor intensive loop. I have never found a need for it because just about everything I use has enough communication (channels or system io) that my programs never get stuck.

There is also GOMAXPROCS which you will probably hear as a solution to this. While it would allow all your goroutines to run by putting them in different threads, the garbage collector would eventually try to run and stop the world. When it stops the world, no goroutines are allowed to run and if the high cpu goroutines never yield, the GC will block goroutines forever but never run.




回答2:


That's because with a single processor, your second goroutine will busy-wait (monopolize the processor by looping and never letting the other goroutine run).

It works if you put, for example, a time.Sleep(time.Millisecond) inside the for loop:

http://play.golang.org/p/M4jeckcmov



来源:https://stackoverflow.com/questions/17953269/go-routine-blocking-the-others-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!