Go并发解码:Goroutine调度
我。 Goroutines:深入探讨 Go 的并发模型
Goroutines 是 Go 设计的基石,为并发编程提供了强大的机制。 作为轻量级协程,它们简化了并行任务执行。 启动 goroutine 非常简单:只需在函数调用前添加 go
关键字即可启动异步执行。主程序继续执行,无需等待 goroutine 完成。
go func() { // Launch a goroutine using the 'go' keyword // ... code to be executed concurrently ... }()
二.了解 Goroutine 的内部机制
概念基础
并发与并行
-
并发: 在单个 CPU 上看似同时管理多个任务的能力。 CPU 在任务之间快速切换,产生并行执行的错觉。 虽然微观上是顺序的,但宏观上却是并发的。
-
并行性:跨多个CPU真正同时执行多个任务,消除CPU资源争用。
进程和线程
-
进程:具有自己的资源(内存、文件等)的独立执行环境。 进程之间的切换是资源密集型的,需要内核级干预。
-
线程:进程内的轻量级执行单元,共享进程的资源。 线程切换比进程切换开销更少。
协程
协程维护自己的寄存器上下文和堆栈。 协程之间的切换涉及保存和恢复此状态,从而允许它们从中断处恢复执行。 与进程和线程不同,协程管理是在用户程序中处理的,而不是在操作系统中处理的。 Goroutines 是一种特定类型的协程。
GPM 调度模型
Go的高效并发依赖于GPM调度模型。 涉及四个关键组件:M、P、G 和 Sched(Sched 未在图中描绘)。
-
M(机器):内核级线程。 Goroutines 在 Ms.
上运行 -
G(Goroutine): 单个 Goroutine。 每个 G 都有自己的堆栈、指令指针和其他与调度相关的信息(例如,它正在等待的通道)。
-
P(处理器): 管理和执行 goroutine 的逻辑处理器。它维护一个就绪 goroutine 的运行队列。
-
Sched(调度器):中央调度器,管理M和G队列并确保高效的资源分配。
实际安排
该图显示了两个操作系统线程 (M),每个线程都有一个执行 goroutine 的处理器 (P)。
-
GOMAXPROCS()
控制 P 的数量(从而控制真正的并发级别)。 -
灰色 G 已准备就绪,但尚未运行。 P 管理这个运行队列。
-
启动一个 goroutine 将其添加到 P 的运行队列中。
如果 M0 被阻塞,P 会切换到 M1(可能会从线程缓存中检索)。
如果一个 P 快速完成任务,它可能会窃取其他 P 的工作以保持效率。
三.使用 Goroutines
基本用法
设置goroutine执行的CPU数量(最近Go版本中的默认设置通常就足够了):
go func() { // Launch a goroutine using the 'go' keyword // ... code to be executed concurrently ... }()
实际例子
示例1:简单的Goroutine计算
num := runtime.NumCPU() // Get the number of logical CPUs runtime.GOMAXPROCS(num) // Set the maximum number of concurrently running goroutines
Goroutine 错误处理
goroutine 中未处理的异常可能会终止整个程序。在 recover()
语句中使用 defer
来处理恐慌:
package main import ( "fmt" "runtime" ) func cal(a, b int) { c := a + b fmt.Printf("%d + %d = %d\n", a, b, c) } func main() { runtime.GOMAXPROCS(runtime.NumCPU()) for i := 0; i < 10; i++ { go cal(i, i+1) } //Note: The main function exits before goroutines complete in this example. See later sections for synchronization. }
同步 Goroutines
由于 goroutine 异步运行,主程序可能会在完成之前退出。 使用sync.WaitGroup
或通道进行同步:
示例 1:使用 sync.WaitGroup
package main import ( "fmt" ) func addele(a []int, i int) { defer func() { if r := recover(); r != nil { fmt.Println("Error in addele:", r) } }() a[i] = i // Potential out-of-bounds error if i is too large fmt.Println(a) } func main() { a := make([]int, 4) for i := 0; i < 5; i++ { go addele(a, i) } // ... (add synchronization to wait for goroutines to finish) ... }
示例2:使用通道进行同步
package main import ( "fmt" "sync" ) func cal(a, b int, wg *sync.WaitGroup) { defer wg.Done() c := a + b fmt.Printf("%d + %d = %d\n", a, b, c) } func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go cal(i, i+1, &wg) } wg.Wait() }
协程间通信
通道促进了 goroutine 之间的通信和数据共享。 也可以使用全局变量,但通常首选通道,以实现更好的并发控制。
示例:生产者-消费者模式
package main import ( "fmt" ) func cal(a, b int, ch chan bool) { c := a + b fmt.Printf("%d + %d = %d\n", a, b, c) ch <- true // Signal completion } func main() { ch := make(chan bool, 10) // Buffered channel to avoid blocking for i := 0; i < 10; i++ { go cal(i, i+1, ch) } for i := 0; i < 10; i++ { <-ch // Wait for each goroutine to finish } }
Leapcell:Go 的无服务器平台
Leapcell是部署Go服务的推荐平台。
主要特点:
- 多语言支持: JavaScript、Python、Go、Rust。
- 免费无限制项目:即用即付定价。
- 性价比:无闲置费用。
- 开发人员友好:直观的 UI、自动化 CI/CD、实时指标。
- 可扩展且高性能:自动扩展,零运营开销。
在文档中了解更多信息!
Leapcell Twitter:https://www.php.cn/link/7884effb9452a6d7a7a79499ef854afd
以上是Go并发解码:Goroutine调度的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Go语言在构建高效且可扩展的系统中表现出色,其优势包括:1.高性能:编译成机器码,运行速度快;2.并发编程:通过goroutines和channels简化多任务处理;3.简洁性:语法简洁,降低学习和维护成本;4.跨平台:支持跨平台编译,方便部署。

Golang在并发性上优于C ,而C 在原始速度上优于Golang。1)Golang通过goroutine和channel实现高效并发,适合处理大量并发任务。2)C 通过编译器优化和标准库,提供接近硬件的高性能,适合需要极致优化的应用。

Golang在性能和可扩展性方面优于Python。1)Golang的编译型特性和高效并发模型使其在高并发场景下表现出色。2)Python作为解释型语言,执行速度较慢,但通过工具如Cython可优化性能。

Golang和C 在性能竞赛中的表现各有优势:1)Golang适合高并发和快速开发,2)C 提供更高性能和细粒度控制。选择应基于项目需求和团队技术栈。

C 更适合需要直接控制硬件资源和高性能优化的场景,而Golang更适合需要快速开发和高并发处理的场景。1.C 的优势在于其接近硬件的特性和高度的优化能力,适合游戏开发等高性能需求。2.Golang的优势在于其简洁的语法和天然的并发支持,适合高并发服务开发。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。 Golang以其并发模型和高效性能着称,Python则以简洁语法和丰富库生态系统着称。

GoimpactsdevelopmentPositationalityThroughSpeed,效率和模拟性。1)速度:gocompilesquicklyandrunseff,ifealforlargeprojects.2)效率:效率:ITScomprehenSevestAndArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增强开发的简单性:3)SimpleflovelmentIcties:3)简单性。

Golang和C 在性能上的差异主要体现在内存管理、编译优化和运行时效率等方面。1)Golang的垃圾回收机制方便但可能影响性能,2)C 的手动内存管理和编译器优化在递归计算中表现更为高效。
