Here is the problem I am trying to solve:
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)
}
The account goroutine receives incoming data on account_chan, executes some work on the data, and once complete sends the data to final_chan. The account work is done by workerA and workerB (order is not important),both must complete on the data before account sends it to final_data. There are a few requirements:
- workerA and workerB are single goroutines
- there should be a constant amount of goroutines at any one time (so no adding new goroutines for each new data item).
My pasted implementation is dumb since now workerA and workerB are never executing concurrently (as they could & should since they are completely independent of each other). So which concurrency pattern can I use to solve this problem?
accountinstead ofaccount_chan(or at leastaccountChan. 2) Your use of channels is pretty weird: Passing ints through channels when a normal function or goroutine call would be enough looks strange. 3) You ask about concurrency; but do you mean parallelism? 4) Depending on the number of physical cores your worker goroutines might never run in parallel. 5) Buffer your wa_{in,out} channels?final_chanuntil both have finished the particular item? IfworkerAgets done first could it helpworkerBwith its items?