原来程序也可以像广场舞大妈一样,同时进行多个任务且井然有序
在这个多核处理器的时代,让程序同时处理多个任务已成为提升性能的关键。Go语言凭借其原生的并发编程模型,让编写并发程序变得像写简单脚本一样轻松。
今天,我们就来深入探讨Go并发编程的核心——goroutine,看看它如何让我们的程序“一心多用”。
并发的艺术:为什么需要goroutine?
在传统编程语言中,实现并发通常意味着使用线程。但线程是重量级的,创建和销毁都需要系统调用,每个线程默认占用大量内存(通常以MB计),且线程间上下文切换成本高昂。
想象一下,你要同时处理10万个网络请求,如果为每个请求创建一个线程,恐怕请求还没处理完,你的服务器内存就先爆了。
Go语言从设计之初就将并发作为核心特性,提出了颠覆性的理念:“不要通过共享内存来通信,而要通过通信来共享内存”。这一理念通过goroutine和channel得以完美实现。
什么是goroutine?轻量到难以置信
goroutine是Go语言中的轻量级线程,由Go运行时(runtime)管理和调度。只需一个go关键字,你就能启动一个并发任务。
package main
import (
"fmt"
"time"
)
func sayHello() {
for i := 0; i < 5; i++ {
fmt.Println("Hello")
time.Sleep(100 * time.Millisecond)
}
}
func main() {
go sayHello() // 就这么简单,一个goroutine就启动了
// 主goroutine继续执行自己的任务
for i := 0; i < 3; i++ {
fmt.Println("Main function")
time.Sleep(100 * time.Millisecond)
}
// 给点时间让sayHello goroutine完成
time.Sleep(time.Second)
}
运行这段代码,你会看到"Hello"和"Main function"交错输出,说明两个任务确实是同时进行的。
goroutine究竟有多轻量?
- 内存占用极小:初始栈大小仅2KB,并且可以按需动态扩缩容。创建100万个goroutine也只需要大约2GB内存(主要开销是堆内存),而100万个Java线程需要TB级内存。
- 创建销毁开销极低:由Go运行时在用户空间管理,不需要系统调用,只是分配一点内存,速度极快。
- 快速启动:比线程快几个数量级。
goroutine背后的魔法:M:N调度模型
Go语言的高并发能力源于其M:N调度模型,这是goroutine的魔法核心。
- Go运行时创建一个少量的OS线程(默认为CPU核心数,如4核机器就创建4个)。
- 成千上万的goroutine被多路复用在这少量的OS线程上。
- Go运行时自身实现了一个工作窃取(Work-Stealin

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



