🖥

Go言語—チャンネルに何もない時の受信では、他のgroutineの処理を待ち続ける (アリスへの手紙)

2023/08/26に公開

これはとある村の、バッファのないチャンネルの話

そしてこれは私の理解。

チャンネルからメッセージを受信しようとする時、なおかつチャンネルにメッセージがない場合は、いったん処理がロック状態になり、他のgoroutineがチャンネルにメッセージ送信するのを待つようだ。

なので、最終的にはどのgroutineもメッセージ送信をおこなわない場合であっても、受信処理では他のgroutineが走り終わるまで待つっぽい。

そして他のgroutine全てが走り終わったタイミングで「もうメッセージ送信をする奴はいない」と分かり、それまでのロック状態がデッドロックと判定されてエラーが起こる模様。

package main

import "fmt"
import "time"

// メインのgoroutineをアリスと呼ぶ
func main() {
	// 何も届かないメールボックス
	mailbox := make(chan string)

	// 何もしない怠惰なボブのgoroutine
	go func() {
		time.Sleep(1000 * time.Millisecond)
		fmt.Println("Bob : I will send letter.")
		time.Sleep(1000 * time.Millisecond)
		fmt.Println("Bob : Umm but it is not today. I will sleep again.")
		time.Sleep(1000 * time.Millisecond)
	}()

	// このメッセージはすぐに表示される
	// アリスには待つ気持ちがあるから
	fmt.Println("Alice : I wait for Bob to send message.")

	// アリスはボブのメッセージをしばらく待つが、いずれ諦めて「デッドロック!」と叫ぶ
	fmt.Println(<-mailbox) // fatal error: all goroutines are asleep - deadlock!
}

The Go Playground

環境

  • go version go1.10.3 darwin/amd64

Gist

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2018-07-28

Discussion