1

我有两个(但稍后我会是三个)处理来自远程服务器(来自 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
}

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

4

3 回答 3

6

您想查看同步包。

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

您将使用互斥锁来执行此操作。

于 2013-03-14T17:27:26.997 回答
3

如果你有一个传入的消息流,并且有三个 goroutine 监听该流并进行处理,并且你想确保一次只有一个 goroutine 在运行,那么解决方案非常简单:杀死两个 goroutine。

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

于 2013-03-14T21:36:49.720 回答
2

我很困惑你为什么想要这个 - 为什么不能deliveries独立处理每条消息?为什么有两个不同的函数处理这些消息?如果每个人都负责一种特定类型的消息,那么您似乎需要一个deliveries接收器来分派到该类型的适当逻辑。

但是要回答你的问题,我认为每个函数都不会truehandleDone一开始就得到一个。一个(假设它是a)正在接收true来自的发送main;另一个(b然后)是false从第一个发送的。因为您正在丢弃收到的值,所以您无法分辨这一点。然后两者都在运行,并且您正在使用缓冲通道(您可能想要make(chan bool)一个无缓冲通道),因此会出现混乱,特别是当您添加第三个 goroutine 时。

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

于 2013-03-14T19:37:31.267 回答