Go语言协程:为什么协程的执行顺序并非我预想的那样?

Go语言协程:为什么协程的执行顺序并非我预想的那样?

深入Go语言协程调度机制:揭秘执行顺序的奥秘

本文将深入探讨Go语言协程的执行顺序问题,澄清一个常见的误解:Go协程的执行并非严格按照启动顺序或先进先出队列进行。 以下示例代码阐述了这一关键点:

  1. package mainimport ( "fmt" "runtime" "sync")func main() { runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(10) for i := 0; i < 10; i++ { if i < 5 { go func() { defer wg.Done() fmt.Println("a:", i) }() } else { go func(num int) { defer wg.Done() fmt.Println("b:", num) }(i - 5) } } wg.Wait()}

登录后复制

这段代码启动了十个协程,前五个使用闭包变量i,后五个使用参数num传递数值。 直觉上,输出顺序应为先打印五个”a:”,再打印五个”b:”,或至少按照启动顺序依次打印。然而,实际运行结果可能出现”b: 4″先打印的情况,这与预期不符。

造成这种现象的原因在于Go语言协程调度器的非确定性。Go 1.5版本之后,协程调度机制发生变化,官方明确指出:不要依赖于goroutine的调度顺序,这是未定义的行为。

立即学习“go语言免费学习笔记(深入)”;

即使设置了runtime.GOMAXPROCS(1)限制为单核运行,也无法保证协程执行顺序的确定性。调度器会根据自身策略选择下一个运行的协程,该策略并非简单的FIFO队列。

因此,闭包变量i的值在协程启动后才最终确定,导致前五个协程都打印了i的最终值5。而后五个协程则正确打印了0到4。”b: 4″能够先执行,是由于调度器的选择,而非任何可预测的顺序。

结论:编写Go代码时,切勿依赖协程的执行顺序。任何依赖未定义行为的代码都是不可靠的。 应使用同步机制(如WaitGroup、通道等)协调协程执行,确保程序按照预期逻辑运行,而非依赖不可预测的调度顺序。

以上就是Go语言协程:为什么协程的执行顺序并非我预想的那样?的详细内容,更多请关注【创想鸟】其它相关文章!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
编程技术

Kubernetes集群中如何可靠地关联Web微服务与日志微服务?

2025-3-31 12:46:33

编程技术

Ent ORM框架中如何正确设置字符串字段长度避免索引过长?

2025-3-31 12:46:40

0 条回复 A文章作者 M管理员
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
私信列表
搜索