Goroutine 协作调度和执行顺序
Go 中的 Goroutines 是协作调度的,这意味着它们显式地将执行交给其他 Goroutine,而不是被抢占由操作系统。这就提出了一个问题:如果一个goroutine没有显式yield,是否会阻止其他goroutine运行?
连续循环的影响
根据文档,运行的goroutine连续而不让步会使同一线程上的其他 goroutine“挨饿”。这是因为永久执行循环的 goroutine 会阻止调度程序将时间片分配给其他 goroutine。
函数调用作为屈服点
但是,需要注意的是Goroutine 中的函数调用可以充当隐式的屈服点。具体来说,调用涉及系统资源的函数(例如网络输入、睡眠、通道操作或阻塞原语)会触发调度程序。
示例场景
考虑一个简单的 Go 程序,启动四个 goroutine,每个 goroutine 执行一个循环并打印一个总和:
func sum(x int) { sum := 0 for i := 0; i < x; i++ { sum += i } fmt.Println(sum) }
如果这些goroutine 与以下同时启动:
go sum(100) go sum(200) go sum(300) go sum(400)
goroutine 不一定会一一执行。在每个 goroutine 末尾进行的 fmt.Println() 调用将触发调度程序,从而允许其他 goroutine 运行。
附加说明
Go 运行时的最新改进引入了让 goroutine 产生执行的额外方法。例如,存在一项提案,将调度程序调用插入到没有任何函数调用的循环中。
总之,虽然没有屈服的连续循环可能会导致单线程环境中的其他 goroutine 挨饿,但函数调用和最近的运行时增强功能提供了即使没有显式让步的情况下,也能实现 goroutine 调度机制。
以上是Go 中连续的 Goroutine 循环会导致其他 Goroutines 饥饿吗?的详细内容。更多信息请关注PHP中文网其他相关文章!