Is it possible in go: Suppose, I have 3 concurrent routines which can send integers to each other. Now, suppose both concurrent routine 2 & 3 sends an integer to concurrent routine 1. Is it possible in go that routine 1 takes both two values and process it farther ? To make it clear, I have following code:
package main
import "rand"
func Routine1(command12 chan int, response12 chan int, command13 chan int, response13 chan int ) {
for i := 0; i < 10; i++ {
i := rand.Intn(100)
if i%2 == 0 {
command12 <- i
}
if i%2 != 0 {
command13 <- i
}
print(<-response13, " 1st
");
}
close(command12)
}
func Routine2(command12 chan int, response12 chan int, command23 chan int, response23 chan int) {
for i := 0; ; i++ {
x, open := <-command12
if !open {
return;
}
print(x , " 2nd
");
y := rand.Intn(100)
if i%2 == 0 {
command12 <- y
}
if i%2 != 0 {
command23 <- y
}
}
}
func Routine3(command13 chan int, response13 chan int, command23 chan int, response23 chan int) {
for i := 0; ; i++ {
x, open := <-command13
if !open {
return;
}
print(x , " 3nd
");
y := rand.Intn(100)
response23 <- y
}
}
func main() {
command12 := make(chan int)
response12 := make(chan int)
command13 := make(chan int)
response13 := make(chan int)
command23 := make(chan int)
response23 := make(chan int)
go Routine1(command12, response12,command13, response13 )
Routine2(command12, response12,command23, response23)
Routine3(command13, response13,command23, response23 )
}
Here, in this example routine 1 can send an int to routine 2 or 3. I assume it is routine 3. Now suppose, routine 3 also send an int to routine 2. Is it possible for routine 2 to take those two values and process further (dynamic concurrent routines)? Can any body help to modify this program accordingly.
I hate abstract examples, anyway I will do my best to answer your question.
Is it possible in go that routine 1 takes both two values and process it farther?
What do you want to archive? Inside routine1 you can either do:
// Read exactly one command from routine2 as well as exactly
// one command from routine3
cmd1 := <-command12
cmd2 := <-command13
// Process the pair of the two commands here
OR
// Process a single command only, which was either sent by routine2
// or by routine3. If there are commands available on both channels
// (command12 and command13) the select statement chooses a branch
// fairly.
select {
case cmd1 := <-command12:
// process command from routine 2
case cmd2 := <-command13
// process command from routine 3
}
I hope that will answer your question. Also note that Go channels support multiple-writers (as well as mutliple readers) by default. So, it might be enough to use exactly one input channel per goroutine. For example, routine1 might only read commands from a channel called command1, but both routine2 and routine3 might use the same command1 channel to send messages to routine1.
Another common idiom in Go is to pass a reply channel as part of the message. For example:
type Command struct {
Cmd string
Reply chan-> int
}
func routine2() {
reply := make(chan int)
command1 <- Command{"doSomething", reply}
status := <-reply
}
func routine1() {
cmd <- command1;
// process cmd.Cmd
cmd.Reply <- 200 // SUCCESS (status code)
}
Depending on your actual problem, this might simplify your program drastically :)
It's not possible in GO, I mean creating concurrent channels.