亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

打印到stdout會導致阻塞的goroutine運行?

打印到stdout會導致阻塞的goroutine運行?

Go
慕容森 2021-04-30 09:10:49
作為一個愚蠢的基本線程練習,我一直在嘗試在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)可能已經改變了。


查看完整回答
反對 回復 2021-05-10
?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

runtime.GOMAXPROCS(2)在主開始處添加即可解決此問題嗎?


查看完整回答
反對 回復 2021-05-10
  • 2 回答
  • 0 關注
  • 266 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號