使用fanIn函数进行多路复用Go协程输出

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

Multiplexing Go Routine Output using fanIn function

问题

我正在尝试实现一个示例Go代码,用于在主函数中使用返回的goroutine通道而没有任何"读取阻塞"。在这里,fanIn函数接受来自两个其他goroutine的通道,并返回输入的通道。

在这里,期望的输出是两个内部goroutine的随机输出。但实际输出总是一个"ann"后跟一个"john",在任何情况下都不是随机的。

为什么我没有得到随机输出?

Go Playground链接:http://play.golang.org/p/46CiihtPwD

实际输出:

  you say: ann,0 
  you say: john,0
  you say: ann,1
  you say: john,1 
   ......

代码:

package main

import (
	"fmt"
	"time"
)

func main() {

	final := fanIn(boring("ann"), boring("john"))

	for i := 0; i < 100; i++ {
		fmt.Println("you say:", <-final)

	}
	time.Sleep(4 * time.Second)
}

func boring(msg string) chan string {
	c1 := make(chan string)
	go func() {
		for i := 0; ; i++ {
			c1 <- fmt.Sprintf("%s,%d", msg, i)
			time.Sleep(time.Second)

		}
	}()
	return c1
}

func fanIn(input1, input2 <-chan string) chan string {
	c := make(chan string)
	go func() {
		for {
			c <- <-input1
		}
	}()
	go func() {
		for {
			c <- <-input2
		}
	}()
	return c
}
英文:

I was trying to implement an example Go code for using returned channels from go routines without any "reading block" in the main function. Here, a fanIn function accepts channels from two other routines and return which got as input.

Here, the expected output is Random Outputs from two inner routines. But the actual output is always one "ann" followed by a "john", not at all random in any case.

Why am I not getting random output?

Go Playground: http://play.golang.org/p/46CiihtPwD

Actual output:

  you say: ann,0 
  you say: john,0
  you say: ann,1
  you say: john,1 
   ......

Code:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {

	final := fanIn(boring(&quot;ann&quot;), boring(&quot;john&quot;))

	for i := 0; i &lt; 100; i++ {
		fmt.Println(&quot;you say:&quot;, &lt;-final)

	}
	time.Sleep(4 * time.Second)
}

func boring(msg string) chan string {
	c1 := make(chan string)
	go func() {
		for i := 0; ; i++ {
			c1 &lt;- fmt.Sprintf(&quot;%s,%d&quot;, msg, i)
			time.Sleep(time.Second)

		}
	}()
	return c1
}

func fanIn(input1, input2 &lt;-chan string) chan string {
	c := make(chan string)
	go func() {
		for {
			c &lt;- &lt;-input1
		}
	}()
	go func() {
		for {
			c &lt;- &lt;-input2
		}
	}()
	return c
}

答案1

得分: 2

没有特定的原因,这只是Go语言在调度相关的goroutine时的一种方式(基本上,你是“幸运的”,因为有一个模式)。你不能依赖它。如果你真的想要一个真正可靠的随机结果,你需要手动混入随机性。

还有一个来自https://github.com/eapache/channels/的Multiplex函数(文档:https://godoc.org/github.com/eapache/channels#Multiplex),它实际上与你的fanIn函数做了相同的事情。不过我认为它在随机性方面的行为不会有任何不同。

英文:

No particular reason, that's just how Go happens to schedule the relevant goroutines (basically, you're getting "lucky" that there's a pattern). You can't rely on it. If you really want an actual reliably random result, you'll have to manually mix in randomness somehow.

There's also the Multiplex function from https://github.com/eapache/channels/ (doc: https://godoc.org/github.com/eapache/channels#Multiplex) which does effectively the same thing as your fanIn function. I don't think it would behave any differently in terms of randomness though.

huangapple
  • 本文由 发表于 2014年8月20日 20:03:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/25404220.html
匿名

发表评论

匿名网友

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

确定