如何将通道作为参数传递给函数?

6
我尝试了两次将一个通道作为参数传递给函数,但它们都失败了(死锁):
尝试1:
func done(signal *chan bool) {
    *signal <- true
}

func main() {
    signal := make(chan bool)
    done(&signal)
    <-signal
    fmt.Println("completed")
}

尝试 2:
func done(signal chan bool) {
    signal <- true
}

func main() {
    signal := make(chan bool)
    done(signal)
    <-signal
    fmt.Println("completed")
}

我已经没有更多的想法了。将通道传递给函数的正确方法是什么?

3
在您的情况(以及几乎所有情况)中,没有理由传递指向 chan、map、slice 或函数值的指针,因为它们都是引用类型,内部已经包含了指针。唯一的例外是,如果您希望被调用方更改引用类型的标头而不是它所引用的数据,那么这里并非如此。 - krait
2个回答

16

默认情况下,通道是无缓冲的,因此当您在通道上发送消息时,该发送操作将被阻塞,直到有人接收到该值。在您的代码中,在执行signal < - true时,没有人能够或将会在同一通道上接收。

您可以创建一个 goroutine 来进行发送操作,这样主函数(main())的执行将会继续,同时有一个接收方来接收该值:

go done(signal)

或者你可以创建一个带缓冲的通道,这样如果通道中有足够的空间来存储值,则在通道发送时不会阻塞:

 signal := make(chan bool, 1)

5

done(&signal)同步调用。也许您想要做的是异步调用它?

为了这样做,在函数调用前加上关键字go

go done(&signal)

主线程将会阻塞,直到done函数向通道中写入内容。而done方法在向通道中写入内容时也会被阻塞,直到主线程读取了该通道中的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接