如何阻止除正在运行的 goroutine 之外的所有 goroutine

我有两个(但稍后我将成为三个)go 例程,它们处理来自远程服务器(来自 ampq 通道)的传入消息。但是因为它们处理相同的数据/状态,所以我想阻止所有其他 go 例程,除了正在运行的那个。


我想出了一个解决方案来使用chan bool每个goroutine阻塞然后释放它,代码如下:


package main


func a(deliveries <-chan amqp, handleDone chan bool) {

    for d := range deliveries {

        <-handleDone        // Data comes always, wait for other channels

        handleDone <- false // Block other channels


        // Do stuff with data...


        handleDone <- true // I'm done, other channels are free to do anything

    }

}


func b(deliveries <-chan amqp, handleDone chan bool) {

    for d := range deliveries {

        <-handleDone

        handleDone <- false

        // Do stuff with data...

        handleDone <- true

    }

}


func main() {

    handleDone := make(chan bool, 1)

    go a(arg1, handleDone)

    go b(arg2, handleDone)

    // go c(arg3, handleDone) , later


    handleDone <- true // kickstart

}

但是第一次每个函数都会 get handleDone <- true,它们将被执行。稍后如果我再添加第三个函数,事情会变得更加复杂。除了 running 之外,如何阻止所有其他 go 程序?还有其他更好的解决方案吗?


倚天杖
浏览 193回答 3
3回答

缥缈止盈

如果您有一个传入的消息流,并且您有三个 goroutine 监听该流并进行处理,并且您想确保一次只有一个 goroutine 在运行,那么解决方案非常简单:杀死两个 goroutine。您正在提高并发性并增加复杂性,然后试图阻止它们并发运行。最终结果与单个流读取器相同,但有很多可能出错的地方。

慕桂英3389331

我很困惑为什么你想要这个 - 为什么不能deliveries独立处理每条消息?为什么有两个不同的函数处理这些消息?如果每个人都负责特定类型的消息,那么您似乎需要一个deliveries接收器来分派该类型的适当逻辑。但是要回答您的问题,我认为每个功能true从handleDone一开始就都不会是真的。一个(假设它是a)正在接收true来自main;&nbsp;另一个(b然后)正在false从第一个发送。因为您正在丢弃收到的值,所以您无法分辨。然后两者都在运行,并且您正在使用缓冲通道(您可能想要make(chan bool)一个无缓冲通道),因此会出现混乱,特别是当您添加第三个 goroutine 时。在handleDone <- false实际上并没有完成任何事情。只需将任何价值handleDone视为接力赛中的接力棒。一旦 goroutine 接收到这个值,它就可以做它的事情;完成后,它应该将其发送到通道以将其交给下一个 goroutine。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go