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

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

為什么程序會在select中被頻道阻塞?

為什么程序會在select中被頻道阻塞?

Go
米脂 2022-10-17 10:16:22
package mainimport (    "fmt")type A struct{    exit chan bool}func (a *A) f(){    select{        //the routine process        //quit        case <- a.exit:                fmt.Println("-----over-----")                a.exit <- true                fmt.Println("+++++over++++++")                      }}func main() {    a := A{}        go a.f()    a.exit = make(chan bool)        a.exit <- true}我想運行多協程,我想讓主函數注意到其他協程退出。這是我的代碼,但是選擇中的程序塊,程序只輸出“-----over-----”,沒有“+++++over++++++”,代碼有什么問題?感謝您幫助。
查看完整描述

1 回答

?
蕪湖不蕪

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

您的程序阻塞,因為這是您編寫的,請考慮以下操作順序:

  1. maingoroutine 啟動a.fgoroutine。

  2. a.f試圖從 nil 通道讀取的塊a.exit

  3. main設置a.exit為無緩沖通道,a.f現在阻止從新通道讀取,這是允許的。

  4. main將值寫入a.exita.f從中讀取值a.exit,這會同步 goroutines,現在下界被阻塞。

  5. a.f現在阻止嘗試寫入 unbuffered a.exit,這將永遠不會解除阻止,因為沒有人會再次嘗試從通道讀取。

  6. main現在退出并導致所有其他 goroutine 退出,這可能發生在第 5 步之前。

所以你的程序從不輸出的原因+++++over++++++是:

  • 你的a.fgoroutine 阻塞,a.exit <- true因為沒有其他 goroutine 會從通道中讀取這個值。

  • 您的goroutine 可能會在完成工作main之前退出并終止整個程序。a.f

我想你是在問如何在 goroutine 完成后讓 main 退出,這是最簡單的例子:

package main


import (

    "fmt"

)


type A struct {

    exit chan struct{}

}


func (a *A) f() {

    defer close(a.exit) // Close the chanel after f() finishes, closed channels yield the zero-value so <-a.exit will unblock


    fmt.Println("+++++over++++++")

}


func main() {

    a := A{}

    go a.f()

    a.exit = make(chan struct{})


    <-a.exit

}


查看完整回答
反對 回復 2022-10-17
  • 1 回答
  • 0 關注
  • 113 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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