Google的Go语言中的并发例程

huangapple go评论65阅读模式
英文:

Concurrent routines in Google's Go Language

问题

在Go语言中是否可能实现以下功能:
假设我有3个并发的例程,它们可以相互发送整数。现在,假设并发例程2和3都向并发例程1发送一个整数。在Go语言中,是否可能让例程1接收这两个值并进一步处理?为了更清楚,我有以下代码:

在这个例子中,例程1可以向例程2或3发送一个整数。我假设是例程3。现在假设例程3也向例程2发送一个整数。是否可能让例程2接收这两个值并进一步处理(动态并发例程)?有人可以帮忙修改这个程序吗?

英文:

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\n");
}
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\n");
    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\n");
    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.

答案1

得分: 2

我讨厌抽象的例子,但是我会尽力回答你的问题。

> 在Go语言中,是否可能让routine1同时接收两个值并进一步处理?

你想要实现什么?在routine1中,你可以选择以下两种方式:

// 从routine2和routine3中分别读取一个命令
cmd1 := <-command12
cmd2 := <-command13
// 在这里处理这两个命令的组合

或者

// 只处理一个命令,该命令可以来自routine2或者routine3。如果两个通道
// (command12和command13)上都有命令可用,select语句会公平地选择一个分支。
select {
    case cmd1 := <-command12:
        // 处理来自routine2的命令
    case cmd2 := <-command13
        // 处理来自routine3的命令
}

希望这能回答你的问题。另外请注意,Go语言的通道默认支持多个写入者(以及多个读取者)。因此,每个goroutine可能只需要使用一个输入通道就足够了。例如,routine1可能只从名为command1的通道中读取命令,而routine2和routine3可能都使用同一个command1通道向routine1发送消息。

Go语言中的另一个常见用法是将回复通道作为消息的一部分传递。例如:

type Command struct {
    Cmd string
    Reply chan-> int
}

func routine2() {
    reply := make(chan int)
    command1 <- Command{"doSomething", reply}
    status := <-reply
}

func routine1() {
    cmd <- command1;
    // 处理cmd.Cmd
    cmd.Reply <- 200 // 成功(状态码)
}

根据你实际的问题,这可能会大大简化你的程序 Google的Go语言中的并发例程

英文:

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 Google的Go语言中的并发例程

答案2

得分: 0

在GO语言中是不可能的,我是指创建并发通道。

英文:

It's not possible in GO, I mean creating concurrent channels.

huangapple
  • 本文由 发表于 2011年11月23日 06:47:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/8234998.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定