【发布时间】:2013-08-30 08:55:12
【问题描述】:
这是我要解决的问题:
package main
import "fmt"
func workerA(work_in_chan <-chan int,work_out_chan chan<- int){
for d := range work_in_chan {
fmt.Println("A ",d)
work_out_chan <- d
}
}
func workerB(work_in_chan <-chan int,work_out_chan chan<- int){
for d := range work_in_chan {
fmt.Println("B ",d)
work_out_chan <- d
}
}
func account(account_chan <-chan int,final_chan chan<- int){
wa_in := make(chan int)
wa_out := make(chan int)
wb_in := make(chan int)
wb_out := make(chan int)
go workerA(wa_in,wa_out)
go workerB(wb_in,wb_out)
for d := range account_chan {
//TODO - dumb implementation starts here
wa_in <- d
<-wa_out
wb_in <- d
<-wb_out
//TODO - dumb implementation ends here
final_chan <- d
}
}
func main() {
account_chan := make(chan int, 100)
final_chan := make(chan int, 100)
go account(account_chan,final_chan)
account_chan <- 1
account_chan <- 2
account_chan <- 3
fmt.Println(<-final_chan)
fmt.Println(<-final_chan)
fmt.Println(<-final_chan)
}
account goroutine 在 account_chan 上接收传入的数据,对数据执行一些工作,一旦完成,将数据发送到 final_chan。账户工作由 workerA 和 workerB 完成(顺序不重要),两者都必须在账户将数据发送到 final_data 之前完成。 有几个要求:
- workerA 和 workerB 是单个 goroutines
- 在任何时候都应该有恒定数量的 goroutine(因此不会为每个新数据项添加新的 goroutine)。
我粘贴的实现是愚蠢的,因为现在 workerA 和 workerB 永远不会同时执行(因为它们可以并且应该因为它们完全相互独立)。那么我可以使用哪种并发模式来解决这个问题呢?
【问题讨论】:
-
1) 如果您寻求大型代码示例的帮助:请考虑编写惯用的 Go 代码,例如
account而不是account_chan(或至少accountChan。2)您对通道的使用非常奇怪:当普通函数或 goroutine 调用足够时通过通道传递整数看起来很奇怪。 3)你问并发;但你的意思是并行性吗? 4) 根据物理内核的数量,您的工作 goroutine 可能永远不会并行运行。 5) 缓冲你的 wa_{in,out} 频道? -
@Volker 1)这是当前项目中使用的命名约定,所以我自然而然地想到了,2)这是一个概念验证示例,在我的真实示例中,我正在传递结构(不是整数)3)我从并发中受益(例如,workerA 通过网络执行某些操作,workerB 写入 fs)4)看看 3 5)没有解决我的问题。
-
您是否正在寻找一种解决方案,一个工人可以完成所有项目,而第二个工人仍在处理第一个。所有这些都要求在
final_chan上都没有发送任何东西,直到双方都完成了特定的项目?如果workerA先完成,它可以帮助workerB处理它的项目吗? -
@deft 代码是,是,不是每个人都只能做自己的工作。
标签: concurrency go