gpt4 book ai didi

concurrency - 寻找 golang 并发模式

转载 作者:IT王子 更新时间:2023-10-29 02:06:19 26 4
gpt4 key购买 nike

这是我要解决的问题:

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。 account 工作由 workerA 和 workerB 完成(顺序不重要),两者都必须在 account 将数据发送到 final_data 之前完成数据。有几个要求:

  • workerA 和 workerB 是单个 goroutine
  • 任何时候都应该有恒定数量的 goroutines(因此不会为每个新数据项添加新的 goroutines)。

我粘贴的实现是愚蠢的,因为现在 workerA 和 workerB 永远不会同时执行(因为它们可以并且应该因为它们完全相互独立)。那么我可以使用哪种并发模式来解决这个问题呢?

最佳答案

根据您提供的限制,我们无能为力。简单地重新排序 channel 操作以允许并发可能就是您所需要的。

for d := range account_chan {
wa_in <- d
wb_in <- d

<-wa_out
<-wb_out

final_chan <- d
}

play.golang.org/p/4d8hKyHTWq
第一次看到这种模式时,我很担心“但是如果 B 先完成怎么办”。事实证明顺序并不重要,因为两者都需要从中接收。


风格旁白:
提供的代码片段听起来像是有太多的 channel 和 goroutines。但这可能是因为这是一个更复杂的问题,被提炼为基本部分。实际上可能存在问题的一件事是 worker 的外出 channel 。他们的输出未在示例中使用,我看不出它如何出现在完整列表中。要么复制值,在这种情况下不需要输出 channel (sync.WaitGroup 会更好),要么它们在工作人员之间共享是不安全的。

关于concurrency - 寻找 golang 并发模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18515098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com