【发布时间】:2016-09-24 23:56:22
【问题描述】:
发件人:http://blog.nindalf.com/how-goroutines-work/
由于协程是协同调度的,一个连续循环的协程可能会饿死同一线程上的其他协程。
Goroutines 很便宜,如果它们被阻塞也不会导致多路复用的线程阻塞
- 网络输入
- 睡觉
- 频道操作或
- 阻止同步包中的原语。
鉴于上述情况,假设您有一些类似这样的代码,除了循环随机次数并打印总和之外什么都不做:
func sum(x int) {
sum := 0
for i := 0; i < x; i++ {
sum += i
}
fmt.Println(sum)
}
如果你使用像这样的 goroutines
go sum(100)
go sum(200)
go sum(300)
go sum(400)
如果你只有一个线程,goroutines 会一个接一个地运行吗?
【问题讨论】:
-
它是特定于实现的(也可能因版本而异),但不是。即使 goroutine 可以在执行过程中阻塞其他程序,也不能保证它们的调度顺序。
-
@JimB 啊好吧,所以他们没有任何定义的顺序,但他们会一个接一个地运行?
-
此外,引用没有提到运行时的最新变化。
fmt.Println(sum)可能会导致其他 goroutine 被调度,因为较新的运行时将在函数调用时调用调度程序。 -
在实践中,它们可能会一个接一个地运行,但规范并没有对顺序做出任何保证,因此应该在假设执行顺序未定义的情况下编写代码。如果您想在 goroutine 之间进行协调,我建议使用通道来控制流程,即阻塞一个例程,直到另一个例程发出信号在通道上完成。
-
文章说不能控制
runtime创建的线程数;因此,将 runtime.GOMAXPROCS 设置为 1 并不能保证只有一个线程。 (根据我对这篇文章的理解,它通常是几个线程)。因此,您的问题似乎更具理论性并且很难测试。但非常有趣。好文章!
标签: multithreading go scheduling goroutine