Là một bài tập luyện cơ bản ngớ ngẩn, tôi đã cố gắng triển khai sleeping barber problem trong golang. Với các kênh này, điều này khá dễ dàng, nhưng tôi đã gặp phải một heisenbug. Đó là, khi tôi cố gắng chẩn đoán nó, vấn đề biến mất!In ấn để stdout khiến goroutine bị chặn chạy?
Hãy xem xét những điều sau đây. Chức năng main()
đẩy các số nguyên (hoặc "khách hàng") vào kênh shop
. barber()
đọc kênh shop
để cắt tóc "của khách hàng". Nếu tôi chèn câu lệnh fmt.Print
vào hàm customer()
, chương trình sẽ chạy như mong đợi. Nếu không, barber()
không bao giờ cắt tóc của bất kỳ ai.
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)
}
}
Bất kỳ ý tưởng nào đang diễn ra?
Câu trả lời của bạn được giữ nếu chỉ có một luồng được thời gian chạy được sử dụng. Thiết lập GOMAXPROCS hoặc thông qua các cuộc gọi thời gian chạy như lazy1 nói hoặc thiết lập biến môi trường cũng sẽ cho phép bất kỳ goroutine nào chạy song song với các goroutine khác trên một luồng riêng biệt. Nó có thể là giá trị mở rộng câu trả lời của bạn để phản ánh cách thời gian chạy của multiplexes goroutines trên các chủ đề có sẵn. –