2016-04-24 6 views
0

私はgolangを勉強しようとしていますが、私はちょっと後につまってしまったのか分かりません。次のコードサンプルが繰り返し実行された後にスタックされるのはなぜですか?

package main 

import "log" 

func main() { 
    deliveryChann := make(chan bool, 10000) 

    go func() { 
     for { 
      deliveryChann <- true 
      log.Println("Sent") 
     } 
    }() 

    go func() { 
     for { 
      select { 
      case <-deliveryChann: 
       log.Println("received") 
      } 
     } 
    }() 

    go func() { 
     for { 
      select { 
      case <-deliveryChann: 
       log.Println("received") 
      } 
     } 
    }() 

    go func() { 
     for { 
      select { 
      case <-deliveryChann: 
       log.Println("received") 
      } 
     } 
    }() 

    for { 
    } 
} 

基本的な調査方法で十分です。

答えて

2

メインのゴルーチン(for {}ループを実行中)はスレッドをホギングしており、他のゴルーチンのどれも実行できません。あなたがあなたのmain関数の最後を変更した場合:

for { 
    runtime.Gosched() 
} 

その後、スレッドが解放され、他のゴルーチンがアクティブになります。

func Gosched()

Goschedは、他のゴルーチンが実行できるように、プロセッサが得られます。現在のgoroutineを中断しないので、実行は自動的に再開します。

- goroutingsの実行のhttps://golang.org/pkg/runtime/#Gosched

+0

そして、ここでの問題のために他のスレッドでスケジュールすることができます。しかし何らかの理由でそれが起こらない – creker

+0

@クレッカー - はい、私は同じことを思った。私は現在原因を確かめていないので、現在調査中です。 – icio

+0

と、デッドロックする前にしばらく走っているという事実をさらに混乱させます。私はそれがすぐにロックされ、それは完全にうまくいくかどうかを理解するだろう。ランタイムがより多くのワーカースレッドを生成する可能性がある前に、プロセスをロックする 'for {} 'のケースに完全に適合します。 – creker

0

順序は未定義です。コードが詰まっていることは合法です。 main()との通信をより決定的にすることができます。 `一つのスレッドだけがロックされます{}のために` GOMAXRPOCS`が1 `より大きい場合に起こるべきではない、他のゴルーチンすることができます - 例の場所

for { 
    deliveryChann <- true 
    log.Println("Sent") 
} 

in main()代わりのgo func()

+0

操作の順序が重要なのはなぜですか?他のルーチンが実行される前にチャネルが開かれます。 goの最新バージョンを実行しているので、cpusの数に問題はありません。 (これがどのように起こるかを理解することが大好きです)。 –

+0

たぶん、バッターの例が、私が何を意味するのかを説明しているかもしれません。http://play.golang.org/p/lrbs5NCEckこれは期待される動作です。 – Uvelichitel

関連する問題