2017-03-17 35 views
2

爲什麼在time.Sleep(time.Nanosecond)被註釋掉時以下程序掛起?goroutine中的循環掛起程序

package main 

import "fmt" 
import "time" 
import "sync/atomic" 

func main() { 
    var ops uint64 = 0 
    for i := 0; i < 50; i++ { 
     go func() { 
      for { 
       atomic.AddUint64(&ops, 1) 
       time.Sleep(time.Nanosecond) 
      } 
     }() 
    } 

    time.Sleep(time.Millisecond) 
    opsFinal := atomic.LoadUint64(&ops) 
    fmt.Println("ops:", opsFinal) 
} 

第二個問題,爲什麼running this program in the sandbox導致「過程花費太長時間」?

回答

6

這是因爲goroutine是合作(不完全搶佔)任務,並且上下文切換隻發生在有一些IO系統調用time.Sleep()或調用必須擴展堆棧的大函數時。

參考:

atomic.AddUint64(&ops, 1)是不具有擴展堆棧小功能。所以上下文切換不會發生。

由於主線程也是一個goroutine,它不會獲取上下文切換,並永遠睡眠。

an open issue使golang先發制人,但尚未解決。

更多有用的參考資料: