作為一個愚蠢的基本線程練習,我一直在嘗試在golang中實現睡眠理發師問題。使用通道,這應該很容易,但是我遇到了heisenbug。也就是說,當我嘗試診斷時,問題消失了!考慮以下。該main()函數將整數(或“客戶”)壓入shop通道。barber()閱讀shop頻道來剪掉“顧客”的頭發。如果我fmt.Print在customer()函數中插入一條語句,程序將按預期運行。否則,barber()切勿剪任何人的頭發。package mainimport "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) }}知道發生什么了嗎?
2 回答

青春有我
TA貢獻1784條經驗 獲得超8個贊
問題是Go的調度程序的實現方式。當前的goroutine只有在進行系統調用或阻塞通道操作時才能屈服于其他goroutine。fmt.Println進行系統調用,使goroutine有機會屈服。否則它沒有一個。
在實踐中,這通常并不重要,但是對于諸如此類的小問題,有時可能會出現。
另外,在通道上進行非阻塞發送的一種更慣用,更省事的方法是:
func customer(id int, shop chan<- int) {
// Enter shop if seats available, otherwise leave
select {
case shop <- id:
default:
}
}
這樣做的方式是,客戶可能最終在理發店外面等了,因為到您實際進行發送時,len(shop)可能已經改變了。
- 2 回答
- 0 關注
- 266 瀏覽
添加回答
舉報
0/150
提交
取消