为了账号安全,请及时绑定邮箱和手机立即绑定

Goroutines - 为什么我只看到最后的并行执行

Goroutines - 为什么我只看到最后的并行执行

Go
心有法竹 2021-07-29 14:11:19
设置我写了这个小程序来看看执行线程是如何工作的。这是一个简化版本,你可以在github上找到完整的func f(from string) { // Bench    // Loop for i < 40 -> fib(i)}func fib(n int64) int { // Something non-linear    // Fibonacci implementation}func main() {    go f("|||") // <- Should alternate    go f("---") // <-    var input string    fmt.Scanln(&input)    fmt.Println("done")}至于输出,前两行||| fib( 0 ): 0--- fib( 0 ): 0然后一切都---取决于--- fib( 28 ): 317811在这一点上|||接管并单独上升到||| fib( 29 ): 514229最后,他们开始“并排”执行,完整的测试转储在这里--- fib( 36 ): 14930352||| fib( 36 ): 14930352--- fib( 37 ): 24157817||| fib( 37 ): 24157817--- fib( 38 ): 39088169||| fib( 38 ): 39088169--- fib( 39 ): 63245986||| fib( 39 ): 63245986问题我最初的假设是 -go f()我应该得到一个相对随机的并行执行,但它以不同大小的块交替,在 29 次调用 'f()' 到第一秒后收敛。为什么?什么是更好的测试?
查看完整描述

2 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

这里有很多事情在起作用。

Go 运行时可以自由地安排你的 goroutines 以任何顺序和任何它喜欢的持续时间运行。因此,您应该获得“并排”执行的假设并不完全有效。此外,很可能您还没有设置 GOMAXPROCS,这意味着运行时默认使用 CPU 的单个核心。如果您设置 GOMAXPROCS > 1,则运行时可以选择在多个内核线程上调度您的 goroutine,而内核又可以将这些线程调度为在 CPU 的多个内核上运行。这可能会给您带来您期望的输出。


查看完整回答
反对 回复 2021-08-02
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

除了 Seth Hoenig 的有用回答之外,并发性和并行性之间存在重要区别。Goroutines 为您提供并发性,这意味着您正在描述理论上同时发生的活动,但只是在抽象意义上。并行是指事情真正同时发生。你的假设是你会立即看到并行性。

习惯于使用 OS 线程的人自然会想到并行性——更快的速度通常是所希望的目标。Goroutines不是操作系统线程,而是允许您设计并发系统,这些系统实际上可能会或可能不会以并行方式执行。目标更多是关于设计的清晰度而不是提高性能……但是您只需一点技巧就可以实现两者。


查看完整回答
反对 回复 2021-08-02
  • 2 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信