Go 并发模式 - 模式 #2

Posted

技术标签:

【中文标题】Go 并发模式 - 模式 #2【英文标题】:Go Concurrency Patterns - Pattern #2 【发布时间】:2014-03-11 03:50:58 【问题描述】:

在视频Google I/O 2012 - Go Concurrency Patterns 中,Rob Pike 在视频中大约 17:00 介绍了多路复用模式。使用 fanIn() 函数,谁准备好谁先说话。

但是当我在here - play.golang.org/p/cvAi5MAAKT中组装程序时,它总是按顺序运行

NumCPU:  4  //Edit#1 output
Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Ann 3
Joe 4
Ann 4

You're both boring: I'm leaving

这段代码有什么问题?

package main

import "fmt"
import "time"
import "math/rand"

//Pattern #2
//Multiplexing
func fanIn(in1, in2 <-chan string) <-chan string 
    c := make(chan string)
    go func() for c <- <-in1()
    go func() for c <- <-in2()
    return c


func boring(msg string) <-chan string 
    c := make(chan string)
    go func() 
        for i := 0; ; i++ 
            c <- fmt.Sprintf("%s %d\n", msg, i)
            time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
        
    ()
    return c


func main() 
    //Edit#1 according to the first answer, add following two lines
    fmt.Println("NumCPU: ", runtime.NumCPU())
    runtime.GOMAXPROCS(runtime.NumCPU())

    c := fanIn(boring("Joe"), boring("Ann"))
    for i := 0; i < 10; i++ 
        fmt.Println(<-c)
    
    fmt.Println("You're both boring: I'm leaving")

更新1: 根据答案,我已经更改了代码,但结果还是一样。我使用的是 Windows 7。请参阅“Edit#1”中的上述更改。

更新2:

我找到了答案:只需将循环数增加到更大的数字(比如 40),即使 GOMAXPROCS 使用默认值,它也会显示不同的顺序。您可以在操场上尝试一下。

【问题讨论】:

【参考方案1】:

没有错,只是您没有告诉 Go 运行时使用多个线程。设置 GOMAXPROCS 环境变量*,或使用runtime 包的runtime.GOMAXPROCS 函数。 GOMAXPROCS 确定 Go 运行时创建的 OS 线程数,以多路复用您创建的 goroutine。如果 GOMAXPROCS 为 1(默认值),您通常会看到非常确定性的行为。

例如在运行程序时:

GOMAXPROCS=4 ./myProgram

例如在你的程序中:

runtime.GOMAXPROCS(runtime.NumCPU())

附: *如果您使用的是 Playground 而不是您自己的机器,GOMAXPROCS 将始终为 1。

【讨论】:

GOMAXPROCS=4 ./myProgram 也可以。这里不需要导出。

以上是关于Go 并发模式 - 模式 #2的主要内容,如果未能解决你的问题,请参考以下文章

Go-并发模式总结(扇入模式,超时模式,callback模式等)

GO常用并发模式

Golang 并发模式

Golang 并发模式

Go语言常见的并发模式

Go并发模式:管道与取消