除了一个运行之外,如何阻止所有goroutine

时间:2013-03-14 17:24:41

标签: go

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

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

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
}

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

3 个答案:

答案 0 :(得分:5)

您想要查看同步包。

http://golang.org/pkg/sync/

您可以使用互斥锁执行此操作。

答案 1 :(得分:3)

如果您有一个传入的消息流,并且您有三个goroutine正在侦听该流并进行处理,并且您希望确保一次只运行一个goroutine,则解决方案非常简单:终止两个goroutine。

您正在提高并发性并增加复杂性,然后尝试阻止它们同时运行。最终结果与单个流阅读器相同,但有很多事情可能出错。

答案 2 :(得分:2)

我很困惑你为什么要这样 - 为什么deliveries上的每条消息都不能独立处理?为什么有两个不同的函数处理这些消息?如果每个消息都对特定类型的消息负责,那么您似乎希望一个deliveries接收方调度该类型的适当逻辑。

但是要回答你的问题,我不认为每个函数在开始时都会从true获得handleDone。一个(假设它是a)正在接收true发送的main;另一个(b然后)正在从第一个发送false。因为你丢弃了收到的价值,你无法说清楚。然后两个都在运行,你正在使用一个缓冲通道(你可能想要make(chan bool)代替一个无缓冲通道),因此会产生混淆,特别是当你添加第三个goroutine时。

handleDone <- false实际上并没有完成任何事情。只需将handleDone上的任何值视为接力赛中的接力棒即可。一旦goroutine收到这个值,它就可以做到这一点;当它完成后,它应该将它发送到通道,将它交给下一个goroutine。

相关问题