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

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

為什么延遲函數不執行?

為什么延遲函數不執行?

Go
楊魅力 2023-08-21 14:41:04
我正在努力理解 Go 中的并發性。package mainimport "fmt"func sendValues(myIntChannel chan int) {    for i := 0; i < 5; i++ {        myIntChannel <- i //sending value    }}func main() {    myIntChannel := make(chan int)    defer close(myIntChannel)    go sendValues(myIntChannel)    for value := range myIntChannel {        fmt.Println(value) //receiving value    }}上面的代碼給出以下輸出:01234fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan receive]:main.main()    /Users/spikki/Desktop/GoLearning/go_channel.go:51 +0x10b根據我的理解,延遲函數將在其周圍函數完成后執行。我無法解釋它。如果我使用 for 循環從通道接收值,其工作原理如下。for i := 0; i < 5; i++ {    fmt.Println(<-myIntChannel) //receiving value}誰能幫助我理解這個概念?
查看完整描述

2 回答

?
BIG陽

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

for ... range僅當從通道接收到所有值并且通道已關閉時,通道上的操作才會終止。


在您的示例中,您希望在延遲函數中關閉通道,但這只會在main()返回時運行。但main()只有在循環結束時才會返回。這就是死鎖的原因。循環for等待通道關閉,關閉通道等待for循環結束。


當您使用循環從通道接收恰好 5 個值時,它會起作用,因為啟動的 Goroutine 會在其上發送 5 個值。該循環不會等待通道關閉,因此循環可以結束,函數也可以結束main()。


這就是為什么發送者應該關閉通道(而不是接收者),問題就立即解決:


func sendValues(myIntChannel chan int) {

    for i := 0; i < 5; i++ {

        myIntChannel <- i //sending value

    }

    close(myIntChannel)

}


func main() {

    myIntChannel := make(chan int)

    go sendValues(myIntChannel)


    for value := range myIntChannel {

        fmt.Println(value) //receiving value

    }

}

輸出(在Go Playground上嘗試):


0

1

2

3

4


查看完整回答
反對 回復 2023-08-21
?
一只萌萌小番薯

TA貢獻1795條經驗 獲得超7個贊

用稍微不同的術語來解釋它,您的代碼的作用是:


func main() {

    ...

    while myIntChannel is not closed {

        ...

    }

    close myIntChannel 

}

現在您可以看到僵局從何而來。


雖然上面的答案是有效的,但如果您更喜歡使用,您也可以嘗試這個defer:


func sendValues(myIntChannel chan int) {

    defer close(myIntChannel)

    for i := 0; i < 5; i++ {

        myIntChannel <- i //sending value

    }

}


func main() {

    myIntChannel := make(chan int)


    go sendValues(myIntChannel)


    for value := range myIntChannel {

        fmt.Println(value) //receiving value

    }

}


查看完整回答
反對 回復 2023-08-21
  • 2 回答
  • 0 關注
  • 222 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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