Печать на стандартный вывод приводит к запуску заблокированной горутины?

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

Есть идеи, что происходит?

7
задан Jjed 14 April 2012 в 15:16
поделиться