私はGoの初心者です、私はこのコードを書いて、デッドロック状態に入ることを望みますが失敗しました。このGoプログラムがデッドロック状態になるのはなぜですか?
var mux sync.Mutex
func main() {
runtime.GOMAXPROCS(1)
for i := 0; i < 3; i++ {
go func() {
log.Println("Trying to Lock the Mux")
mux.Lock()
log.Println("The mux is Locked")
}()
}
runtime.Gosched()
}
//Output:
//2017/01/17 08:59:42 Trying to Lock the Mux
//2017/01/17 08:59:42 The mux is Locked
//2017/01/17 08:59:42 Trying to Lock the Mux
//2017/01/17 08:59:42 Trying to Lock the Mux
ご覧のとおり、このコードはうまく動いて何かを印刷し、デッドロックエラーなしで終了します。私が知っているのは、最初のものです。go func(){} goroutineはmuxを返してロックしてから終了しました。しかし、他の2つのゴルーチンは、マルチプレクサが既にブロックされているためブロックされます。
runtime.Gosched機能()は右のみFIFOキュー(runtime.GOMAXPROCS(1))にメインゴルーチンをプッシュする必要がありますか?それはなぜキューの左にある2つのgoroutineの前にexcuteすることができますか?
ところで、この次のコードは期待
var mux sync.Mutex
func main() {
runtime.GOMAXPROCS(1)
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func() {
defer wg.Done()
log.Println("Trying to Lock the Mux")
mux.Lock()
log.Println("The mux is Locked")
}()
}
wg.Wait()
}
感謝としてデッドロックエラーが返されます!あなたのコードの場合
ランタイムはここには何もしないので、意図はわかりません。あなたはプログラムがデッドロックしていない、メインのgoroutineは継続して終了します。 – JimB
私が知っているように、Gosched()はメインのゴルーチンをキューに押し戻し、すべてのゴルーチンが完了するのを待ちます。 – MikeZhang
Goschedがブロックキューにgoroutineを置くという考えがどこにあるのか分かりませんが、それは間違っています。 "Goschedはプロセッサを生成し、他のゴルーチンを実行できるようにします。現在のゴルーチンを一時停止しないので、実行は自動的に再開します。" – JimB