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

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

當向 Go 例程之外的通道發送值時,Go 例程會出現死鎖

當向 Go 例程之外的通道發送值時,Go 例程會出現死鎖

Go
慕田峪7331174 2023-07-04 19:05:56
我在 Golang 教程中學習 Go select 語句時嘗試對代碼進行一些更改: https: //tour.golang.org/concurrency/5。但是,我遇到了問題:fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:main.main()        concurrency.go:26 +0xa3goroutine 33 [chan receive]:main.main.func1(0xc000088000)        concurrency.go:24 +0x42created by main.main        concurrency.go:23 +0x89exit status 2這是我嘗試并遇到問題的代碼func fibonacci(c, quit chan int) {    x, y := 0, 1    for {        select {            case c <- x:  //sending value x into channel c                x, y = y, x+y            case <-quit:    //receive value from quit                fmt.Println("quit")        return        }    }}func main() {    //create two channels    c := make(chan int)    quit := make(chan int)    go func() { //spin off the second function in order to let consume from c , so fibonaci can continue to work        fmt.Println(<-c)    //read value from channel c    }()    //Try moving the statement that send value to channel quit in order to     //return function fibonacci    quit <- 0       fibonacci(c, quit)}起初,我認為結果將與下面代碼的結果相同//function fibonacci is same with the first onefunc fibonacci(c, quit chan int) {    x, y := 0, 1    for {        select {            case c <- x:  //sending value x into channel c                x, y = y, x+y            case <-quit:    //receive value from quit                fmt.Println("quit")        return        }    }}func main() {    //create two channels    c := make(chan int)    quit := make(chan int)    go func() { //spin off the second function in order to let consume from c , so fibonaci can continue to work        fmt.Println(<-c)    //read value from channel c        quit <- 0 //CHANGE: move the statement inside the closure function     }()    fibonacci(c, quit)}輸出是0quit您能解釋一下執行第一個示例時死鎖的根本原因是什么嗎?在go例程中發送值退出通道與在主線程中發送值退出通道有什么區別?感謝你們。
查看完整描述

1 回答

?
寶慕林4294392

TA貢獻2021條經驗 獲得超8個贊

該quit通道是無緩沖通道。在發送和接收 goroutine 都準備好之前,無緩沖通道上的通信不會繼續。該語句quit <- 0在應用程序執行函數以接收值之前阻塞。接收 Goroutine 永遠不會準備好


通過關閉通道修復:


c := make(chan int)

quit := make(chan int)

go func() {

    fmt.Println(<-c)

}()

close(quit)

fibonacci(c, quit)

...或者通過緩沖通道


c := make(chan int, 1) // <- note size 1

quit := make(chan int)

go func() { 

    fmt.Println(<-c) 

}()

quit <- 0   

fibonacci(c, quit)

在這種情況下,fibonacci將在產生值之前退出。


查看完整回答
反對 回復 2023-07-04
  • 1 回答
  • 0 關注
  • 130 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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