它是并发的,但是是什么让它并行运行呢?

Gar*_*ett 0 go

所以我试图在学习 Go 的同时了解并行计算的工作原理。我理解并发和并行之间的区别,但是,我有点困惑的是 Go(或操作系统)如何确定某些内容应该并行执行......

在编写代码时我必须做一些事情,还是所有事情都由调度程序处理?

在下面的示例中,我有两个函数使用 go 关键字在单独的 Go 例程中运行。因为默认的 GOMAXPROCS 是您机器上可用的处理器数量(并且我也明确设置了它),所以我希望这两个函数同时运行,因此输出将是按特定顺序排列的数字的混合 - 并且此外,每次运行的输出都会不同。然而,这种情况并非如此。相反,它们一个接一个地运行,更令人困惑的是,函数二在函数一之前运行。

代码:

func main() {
    runtime.GOMAXPROCS(6)
    var wg sync.WaitGroup
    wg.Add(2)

    fmt.Println("Starting")
    go func() {
        defer wg.Done()
        for smallNum := 0; smallNum < 20; smallNum++ {
            fmt.Printf("%v ", smallNum)
        }
    }()

    go func() {
        defer wg.Done()
        for bigNum := 100; bigNum > 80; bigNum-- {
            fmt.Printf("%v ", bigNum)
        }
    }()

    fmt.Println("Waiting to finish")
    wg.Wait()

    fmt.Println("\nFinished, Now terminating")
}
Run Code Online (Sandbox Code Playgroud)

输出:

go run main.go
Starting
Waiting to finish
100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
Finished, Now terminating
Run Code Online (Sandbox Code Playgroud)

我正在关注这篇文章,尽管我遇到的几乎每个例子都做了类似的事情。 并发、Goroutines 和 GOMAXPROCS

这是否按照应该的方式工作,而我没有正确理解某些内容,或者我的代码不正确?

Vol*_*ker 5

编写代码时我必须做些什么吗?

不。

或者这一切都由调度程序处理?

是的。

在下面的示例中,我有两个函数使用 go 关键字在单独的 Go 例程中运行。因为默认的 GOMAXPROCS 是您机器上可用的处理器数量(并且我也明确设置了它),所以我希望这两个函数同时运行

他们可能会也可能不会,你无法控制。

因此输出将是特定顺序的数字的混合 - 而且每次运行时输出都会不同。然而,这种情况并非如此。相反,它们一个接一个地运行,更令人困惑的是,函数二在函数一之前运行。

是的。同样,您不能强制并行计算。

你的测试是有缺陷的:你只是在每个 goroutine 中没有做太多事情。在您的示例中,goroutine 2 可能会被安排运行、开始运行并在 goroutine 1 开始运行之前完成。“启动”一个 goroutinego并不强制它立即开始执行,所要做的只是创建一个可以运行的新 goroutine。所有可以运行的 goroutine 中的一些都被调度到您的处理器上。所有这些调度都无法控制,它是全自动的。正如您似乎知道的那样,这是并发和并行之间的区别。您可以控制 Go 中的并发性,但不能控制在两个或更多内核上实际并行执行的操作。

更实际的例子是实际的、长期运行的 goroutine,它们执行实际的工作,将显示交错的输出。