Goroutine 超越系统调用的收益点
在 Go 程序中,goroutine 是并发的主要机制。虽然会阻塞 Goroutine 的系统调用是已知的让出点,但如果不考虑其他可能的让出点,对 Goroutine 调度的理解就不完整。
一个可疑的让出点是函数调用,因为它们需要调度程序检查堆栈生长。然而,有人指出,如果它只执行数学运算,“一个 goroutine 将锁定线程,直到它退出或遇到可能让其他线程执行的东西”。
为了测试这一点,创建了一个运行的程序三个循环(一个在主函数中,两个在单独的 goroutine 中),没有任何函数调用。程序将 GOMAXPROCS 设置为 1,限制可以并发执行 Go 代码的操作系统线程数量。然而,输出仍然显示来自主函数和 goroutine 的交错消息,这表明即使没有函数调用,goroutine 也会进行屈服控制。
这种明显差异的答案在于 Go 1.14 中引入的异步抢占,这增加了潜力抢占点几乎无处不在。因此,除了阻塞系统调用之外,goroutines 还可以在各个点上让出控制权。
虽然抢占点的具体实现可能在 Go 版本之间发生变化,但异步抢占可确保没有函数调用的循环不再使调度程序死锁或显着延迟垃圾收藏。尽管如此,值得注意的是,不同步的数组写入和非原子索引更新可能会引入可能影响程序行为的协作调度点。
以上是除了系统调用和函数调用之外,Goroutine 是否还能产生控制?的详细内容。更多信息请关注PHP中文网其他相关文章!