为什么程序会在select中被频道阻塞?

package main


import (

    "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++++++”,代码有什么问题?感谢您帮助。


米脂
浏览 71回答 1
1回答

芜湖不芜

您的程序阻塞,因为这是您编写的,请考虑以下操作顺序:maingoroutine 启动a.fgoroutine。a.f试图从 nil 通道读取的块a.exit。main设置a.exit为无缓冲通道,a.f现在阻止从新通道读取,这是允许的。main将值写入a.exit并a.f从中读取值a.exit,这会同步 goroutines,现在下界被阻塞。a.f现在阻止尝试写入 unbuffered&nbsp;a.exit,这将永远不会解除阻止,因为没有人会再次尝试从通道读取。main现在退出并导致所有其他 goroutine 退出,这可能发生在第 5 步之前。所以你的程序从不输出的原因+++++over++++++是:你的a.fgoroutine 阻塞,a.exit <- true因为没有其他 goroutine 会从通道中读取这个值。您的goroutine 可能会在完成工作main之前退出并终止整个程序。a.f我想你是在问如何在 goroutine 完成后让 main 退出,这是最简单的例子:package mainimport (&nbsp; &nbsp; "fmt")type A struct {&nbsp; &nbsp; exit chan struct{}}func (a *A) f() {&nbsp; &nbsp; defer close(a.exit) // Close the chanel after f() finishes, closed channels yield the zero-value so <-a.exit will unblock&nbsp; &nbsp; fmt.Println("+++++over++++++")}func main() {&nbsp; &nbsp; a := A{}&nbsp; &nbsp; go a.f()&nbsp; &nbsp; a.exit = make(chan struct{})&nbsp; &nbsp; <-a.exit}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go