首页 > 后端开发 > Golang > 正文

Go 并发编程中的 Goroutine 调度与执行顺序

心靈之曲
发布: 2025-09-09 19:17:01
原创
808人浏览过

go 并发编程中的 goroutine 调度与执行顺序

在 Go 语言中,Goroutine 是一种轻量级的并发执行单元,允许程序同时执行多个任务。然而,由于 Goroutine 的调度是由 Go 运行时环境控制的,因此 Goroutine 之间的执行顺序并非总是如我们预期的那样。 理解 Goroutine 的调度机制对于编写健壮的并发程序至关重要。

Goroutine 调度机制

Go 语言的 Goroutine 调度器负责将 Goroutine 分配到可用的 CPU 核心上执行。默认情况下,Go 运行时环境使用单个操作系统线程来执行所有的 Goroutine。这意味着 Goroutine 实际上是在用户空间中进行上下文切换,而非真正的并行执行。

GOMAXPROCS 环境变量或 runtime.GOMAXPROCS() 函数可以用来设置 Go 运行时环境可以使用的最大 CPU 核心数。当 GOMAXPROCS 大于 1 时,Go 运行时环境将创建多个操作系统线程,从而允许 Goroutine 在多个 CPU 核心上并行执行。

示例代码分析

考虑以下示例代码:

package main

import (
    "fmt"
    "time"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(2) // 设置使用 2 个 CPU 核心
    go sheep(1)
    go sheep(2)
    time.Sleep(time.Second * 2) // 等待 Goroutine 执行一段时间
}

func sheep(i int) {
    for {
        fmt.Println(i, "sheeps")
        i += 2
        //runtime.Gosched() // 显式让出 CPU 时间片
        time.Sleep(time.Millisecond * 100) // 降低打印速度,方便观察
    }
}
登录后复制

这段代码创建了两个 Goroutine,分别打印奇数和偶数。在单核 CPU 环境下,或者当 GOMAXPROCS 为 1 时,程序很可能先打印所有的奇数,然后再打印所有的偶数。这是因为 Go 运行时环境会先执行完一个 Goroutine,然后再执行另一个 Goroutine。

设置 runtime.GOMAXPROCS(2) 后,程序更有可能交替打印奇数和偶数。 这是因为两个 Goroutine 可以同时在不同的 CPU 核心上运行。

小艺
小艺

华为公司推出的AI智能助手

小艺 549
查看详情 小艺

使用 runtime.Gosched() 让出 CPU 时间片

runtime.Gosched() 函数可以显式地让出当前 Goroutine 的 CPU 时间片,允许其他 Goroutine 运行。在上面的 sheep 函数中,添加 runtime.Gosched() 调用可以强制 Go 运行时环境在每次打印数字后切换到另一个 Goroutine。

func sheep(i int) {
    for {
        fmt.Println(i, "sheeps")
        i += 2
        runtime.Gosched() // 显式让出 CPU 时间片
        time.Sleep(time.Millisecond * 100) // 降低打印速度,方便观察
    }
}
登录后复制

虽然使用 runtime.Gosched() 可以影响 Goroutine 的执行顺序,但它并不能保证 Goroutine 的执行顺序。 Goroutine 的调度仍然是由 Go 运行时环境控制的,并且可能会受到其他因素的影响。

Goroutine 间同步

并发编程中,为了保证数据的一致性和避免竞争条件,通常需要使用同步机制来协调 Goroutine 之间的执行。Go 语言提供了多种同步机制,包括 sync.Mutex、sync.WaitGroup 和 channel。

  • sync.Mutex: 互斥锁,用于保护共享资源,防止多个 Goroutine 同时访问。
  • sync.WaitGroup: 用于等待一组 Goroutine 完成。
  • Channel: 用于 Goroutine 之间的通信和同步。

在上面的示例代码中,如果需要保证奇数和偶数交替打印,可以使用 channel 来进行同步。

注意事项

  • 不要依赖 Goroutine 的执行顺序。 Goroutine 的调度是由 Go 运行时环境控制的,并且可能会受到多种因素的影响。
  • 使用同步机制来协调 Goroutine 之间的执行,保证数据的一致性和避免竞争条件。
  • 合理设置 GOMAXPROCS,充分利用多核 CPU 的优势。
  • runtime.Gosched() 只能影响 Goroutine 的执行顺序,但不能保证 Goroutine 的执行顺序。

总结

Go 语言的 Goroutine 是一种强大的并发编程工具。理解 Goroutine 的调度机制,合理使用同步机制,可以编写出高效、健壮的并发程序。 在实际开发中,应避免对 Goroutine 的执行顺序做出假设,而是应该使用适当的同步机制来保证程序的正确性。

以上就是Go 并发编程中的 Goroutine 调度与执行顺序的详细内容,更多请关注php中文网其它相关文章!

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号