如何阻止除了正在运行的所有goroutines

问题描述:

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

我想出了一个解决方案中使用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,他们将被执行。如果我添加另一个第三个函数,事情会变得更加复杂。如何阻止除运行之外的其他所有例程?其他更好的解决方案?

+0

我不认为你的频道做你认为他们做的事,因为你从来没有检查收到的价值。无论如何,使用缓冲通道作为互斥/信号可能是危险的。改用实际的Mutex。 – JimB 2013-03-15 14:34:22

+0

请注意,它们被称为“goroutines”,而不是“go routines”。这是因为“例程”这个词可能是指任何程序PL中的任何过程/函数,因此“go routines”听起来像“Go中的例程”,这使术语的预期意义消失。 – kostix 2013-04-29 07:29:07

你想看看同步包。

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

你会用互斥做到这一点。

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

但是要回答你的问题,我不认为每个功能在开始时都会从handleDone获得true。一个(假设它是a)正在接收从main发送的true;其他(b然后)得到从第一个发送的false。因为你丢弃了收到的价值,所以你不能说出这个。然后两者都在运行,并且您正在使用缓冲通道(您可能希望使用make(chan bool)而不是无缓冲的通道),因此会引起混淆,特别是在添加第三个goroutine时。

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

+0

感谢您的评论。我已经更改了代码的某些部分。我删除了'false's。但它现在变成了一堆,它只是在那里等着。它只是在两个go函数的' 2013-03-14 20:39:16

+0

什么是'main'这样做?它是否已经达到'handleDone 2013-03-14 20:46:34

+0

问题是,'handleDone 2013-03-14 20:51:57

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

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