ばかげた基本的なスレッド化の演習として、私は睡眠中の床屋問題を golang で実装しようとしました。チャネルを使用すると、これは非常に簡単なはずですが、ハイゼンバグに遭遇しました。つまり、診断しようとすると、問題が消えます!
以下を検討してください。このmain()
関数は整数 (または「顧客」) をshop
チャネルにプッシュします。barber()
チャネルを読み取り、shop
「顧客」の髪をカットします。fmt.Print
関数にステートメントを挿入するcustomer()
と、プログラムは期待どおりに実行されます。そうでなければ、barber()
誰の髪も決して切らない。
package main
import "fmt"
func customer(id int, shop chan<- int) {
// Enter shop if seats available, otherwise leave
// fmt.Println("Uncomment this line and the program works")
if len(shop) < cap(shop) {
shop <- id
}
}
func barber(shop <-chan int) {
// Cut hair of anyone who enters the shop
for {
fmt.Println("Barber cuts hair of customer", <-shop)
}
}
func main() {
shop := make(chan int, 5) // five seats available
go barber(shop)
for i := 0; ; i++ {
customer(i, shop)
}
}
何が起こっているのか分かりますか?