如何阻止除了正在运行的所有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
,他们将被执行。如果我添加另一个第三个函数,事情会变得更加复杂。如何阻止除运行之外的其他所有例程?其他更好的解决方案?
我很困惑你为什么要这样 - 为什么不能在deliveries
上独立处理每条消息?为什么有两个不同的函数处理这些消息?如果每个人都对特定类型的消息负责,那么您似乎希望一个deliveries
接收器调度到该类型的适当逻辑。
但是要回答你的问题,我不认为每个功能在开始时都会从handleDone
获得true
。一个(假设它是a
)正在接收从main
发送的true
;其他(b
然后)得到从第一个发送的false
。因为你丢弃了收到的价值,所以你不能说出这个。然后两者都在运行,并且您正在使用缓冲通道(您可能希望使用make(chan bool)
而不是无缓冲的通道),因此会引起混淆,特别是在添加第三个goroutine时。
handleDone <- false
实际上并没有完成任何事情。只要将handleDone
上的任何值视为接力比赛中的接力棒。一旦一个门厅收到这个价值,它就可以做到这一点;当它完成后,它应该将它发送到频道以将其传送到下一个goroutine。
感谢您的评论。我已经更改了代码的某些部分。我删除了'false's。但它现在变成了一堆,它只是在那里等着。它只是在两个go函数的' 2013-03-14 20:39:16
什么是'main'这样做?它是否已经达到'handleDone 2013-03-14 20:46:34
问题是,'handleDone 2013-03-14 20:51:57
如果您有一个传入的消息流,并且您有三个监听该流和处理的goroutine,并且您希望确保一次只运行一个goroutine,则解决方案非常简单:关闭两个goroutine 。
您正在旋转并发并增加复杂性,然后尝试阻止它们同时运行。最终的结果与单流阅读器相同,但有很多事情可能出错。
我不认为你的频道做你认为他们做的事,因为你从来没有检查收到的价值。无论如何,使用缓冲通道作为互斥/信号可能是危险的。改用实际的Mutex。 – JimB 2013-03-15 14:34:22
请注意,它们被称为“goroutines”,而不是“go routines”。这是因为“例程”这个词可能是指任何程序PL中的任何过程/函数,因此“go routines”听起来像“Go中的例程”,这使术语的预期意义消失。 – kostix 2013-04-29 07:29:07