В качестве глупого базового упражнения с многопоточностью я пытался реализовать задачу о спящем парикмахере на 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)
}
}
Есть идеи, что происходит?