2017-03-17 7 views
2

time.Sleep(time.Nanosecond)がコメントアウトされていると、次のプログラムがハングするのはなぜですか?ゴルーチンのループがプログラムをハングする

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) 
} 

2つ目の質問は、なぜでrunning this program in the sandbox結果「プロセスは時間がかかりすぎた」のでしょうか?

答えて

6

これはゴルーチンが協力的(完全にプリエンプティブではない)のタスクであり、IO、システムコール、time.Sleep()、またはスタックを拡張する必要がある大きな関数を呼び出すときにのみコンテキスト切り替えが発生するためです。

参考:

あなたatomic.AddUint64(&ops, 1)はスタックを拡張する必要はありません小さな関数です。コンテキストスイッチは決して発生しません。

メインスレッドもゴルーチンであるため、コンテキスト切り替えを取得せず、永久にスリープします。

ゴールンをタイトループでプリエンプティブにするには、まだ解決していませんが、an open issueがあります。

もっと便利参照:

関連する問題