第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

為什么在同一個 goroutine 中使用無緩沖通道會導(dǎo)致死鎖?

為什么在同一個 goroutine 中使用無緩沖通道會導(dǎo)致死鎖?

Go
手掌心 2021-06-16 21:01:23
我確信對這種微不足道的情況有一個簡單的解釋,但我是go并發(fā)模型的新手。當(dāng)我運(yùn)行這個例子時package mainimport "fmt"func main() {    c := make(chan int)        c <- 1       fmt.Println(<-c)}我收到此錯誤:fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:main.main()    /home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52exit status 2為什么 ?包裹c(diǎn) <-在 agoroutine中使示例按預(yù)期運(yùn)行package mainimport "fmt"func main() {    c := make(chan int)            go func(){       c <- 1    }()    fmt.Println(<-c)}再說一遍,為什么?拜托,我需要深入的解釋,而不僅僅是如何消除死鎖和修復(fù)代碼。
查看完整描述

3 回答

?
喵喵時光機(jī)

TA貢獻(xiàn)1846條經(jīng)驗(yàn) 獲得超7個贊

在無緩沖通道中寫入通道不會發(fā)生,直到必須有一些接收器等待接收數(shù)據(jù),這意味著在下面的例子中


func main(){

    ch := make(chan int)

    ch <- 10   /* Main routine is Blocked, because there is no routine to receive the value   */

    <- ch

}

現(xiàn)在如果我們有其他 goroutine,同樣的原則適用


func main(){

  ch :=make(chan int)

  go task(ch)

  ch <-10

}

func task(ch chan int){

   <- ch

}

這將起作用,因?yàn)槿蝿?wù)例程正在等待數(shù)據(jù)被使用,然后寫入發(fā)生到無緩沖通道。


為了更清楚,讓我們交換主函數(shù)中第二條和第三條語句的順序。


func main(){

  ch := make(chan int)

  ch <- 10       /*Blocked: No routine is waiting for the data to be consumed from the channel */

  go task(ch)

}

這會導(dǎo)致死鎖


所以簡而言之,只有當(dāng)有一些例程等待從通道讀取時才會寫入無緩沖通道,否則寫入操作將被永遠(yuǎn)阻塞并導(dǎo)致死鎖。


注意:相同的概念適用于緩沖通道,但在緩沖區(qū)已滿之前不會阻止發(fā)送方,這意味著接收方不一定要與每個寫操作同步。


因此,如果我們有大小為 1 的緩沖通道,那么您上面提到的代碼將起作用


func main(){

  ch := make(chan int, 1) /*channel of size 1 */

  ch <-10  /* Not blocked: can put the value in channel buffer */

  <- ch 

}

但是如果我們給上面的例子寫更多的值,那么就會發(fā)生死鎖


func main(){

  ch := make(chan int, 1) /*channel Buffer size 1 */

  ch <- 10

  ch <- 20 /*Blocked: Because Buffer size is already full and no one is waiting to recieve the Data  from channel */

  <- ch

  <- ch

}


查看完整回答
反對 回復(fù) 2021-06-28
?
蕪湖不蕪

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超7個贊

在這個答案中,我將嘗試解釋錯誤消息,通過它我們可以稍微了解 go 在通道和 goroutines 方面的工作原理


第一個例子是:


package main


import "fmt"


func main() {

    c := make(chan int)    

    c <- 1   

    fmt.Println(<-c)

}

錯誤信息是:


fatal error: all goroutines are asleep - deadlock!

在代碼中,根本沒有 goroutines(順便說一句,這個錯誤是在運(yùn)行時,而不是編譯時)。當(dāng) go 運(yùn)行此行時c <- 1,它希望確保通道中的消息將在某處(即<-c)收到。Go 不知道此時是否會收到頻道。因此,go 將等待正在運(yùn)行的 goroutine 完成,直到發(fā)生以下任一情況:


所有的 goroutine 都完成了(睡著了)

goroutine 之一嘗試接收通道

在第 1 種情況下,go 會出錯并顯示上面的消息,因?yàn)楝F(xiàn)在 go 知道 goroutine 無法接收通道并且它需要一個。


在第 2 種情況下,程序?qū)⒗^續(xù),因?yàn)楝F(xiàn)在知道收到了這個頻道。這解釋了 OP 示例中的成功案例。


查看完整回答
反對 回復(fù) 2021-06-28
  • 3 回答
  • 0 關(guān)注
  • 253 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號