【问题标题】:Golang: Why are goroutines not running in parallel?Golang:为什么 goroutine 不能并行运行?
【发布时间】:2017-05-18 05:24:51
【问题描述】:

我有以下示例,其中两个 goroutine 应该并行运行。但是如果你检查输出,第二个 goroutine 只会在第一个 goroutine 完成后运行。所以,它是顺序的。

添加 2 个处理器:runtime.GOMAXPROCS(2) 也没有帮助。我在 8 核的 Mac pro 上运行,这绝对不是硬件问题。 所以我的问题 - Golang 真的是平行的吗?如何让下面的例子运行 并行?

输出:

Thread 1
Thread 1
  …………....
Thread 1
Thread 1
Thread 2
Thread 2
  …………....
Thread 2
Thread 2

转码:

package main

import (
    "runtime"
    "time"
)

func main() {

    runtime.GOMAXPROCS(2)

    go func() {
        for i := 0; i < 100; i++ {
            println("Thread 1")
            //time.Sleep(time.Millisecond * 10)
        }
    }()

    go func() {
        for i := 0; i < 100; i++ {
            println("Thread 2")
            //time.Sleep(time.Millisecond * 10)
        }
    }()

    time.Sleep(time.Second)
}

【问题讨论】:

  • “所以,它是连续的。”不它不是。你有什么问题?
  • 如果你想查看并行运行的goroutine,你可以尝试使用runtime.LockOSThread()Playground。但它不能保证这些线程在不同的 cpu 上运行。也许你可以在这里得到想法:stackoverflow.com/a/19759235/694331
  • @Volker:为什么不是顺序的?如果我们有 2 个进程 Go 运行时不会将每个 goroutine 分离到单独的进程/线程,这清楚地表明了。问为什么?
  • Goroutines 不是“并行”运行,而是同时运行。形式上,您不能强制 Go 程序的两个部分同时执行。您所能做的就是:使其可能“并行”(同时)执行。或者不可能。不允许调度程序控制执行的紧密或短循环是阻止“并行”执行的代码示例之一。阅读blog.golang.org/concurrency-is-not-parallelism

标签: multithreading go parallel-processing


【解决方案1】:

为了了解你的程序是并行运行还是并发运行,goroutine 是按顺序打印不同的值。 来自这篇文章:Concurrency, Goroutines and GOMAXPROCS

您的代码表达量不足以表示并行调用。请看下面的代码。

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    runtime.GOMAXPROCS(2)

    var wg sync.WaitGroup
    wg.Add(2)

    fmt.Println("Starting Go Routines")
    go func() {
        defer wg.Done()

        //time.Sleep(1 * time.Microsecond)
        for char := 'a'; char < 'a'+26; char++ {
            fmt.Printf("%c ", char)
        }
    }()

    go func() {
        defer wg.Done()

        for number := 1; number < 27; number++ {
            fmt.Printf("%d ", number)
        }
    }()

    fmt.Println("Waiting To Finish")
    wg.Wait()

    fmt.Println("\nTerminating Program")
}

从上面的代码中可以看出,使用 for 循环打印不同的值序列。

如果您注释 runtime.GOMAXPROCS(2) 并取消注释 time.Sleep(1 * time.Microsecond) 上的行,输出会有所不同。

【讨论】:

  • 文章链接似乎已失效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
相关资源
最近更新 更多