質問

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")
    }
}
役に立ちましたか?

解決

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.

他のヒント

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top