
Go语言的并发编程核心是goroutine和channel它们共同构成了Go轻量、简洁、安全的并发模型。Goroutine是Go运行时管理的轻量级线程协程由go关键字启动开销极小初始栈仅2KB可轻松创建成千上万个。例如gofunc(){fmt.Println(Hello from goroutine!)}()Channel是goroutine间通信的管道类型安全、带同步语义用于传递数据并协调执行。声明与使用示例ch:make(chanint,1)// 创建带缓冲的int通道gofunc(){ch-42}()// 发送val:-ch// 接收阻塞直到有值关键特性无共享内存Share memory by communicating避免传统锁竞争channel默认为同步无缓冲时发送/接收配对才继续天然支持“等待完成”、“生产者-消费者”等模式select语句可多路复用多个channel操作实现非阻塞或超时控制。⚠️ 初学注意goroutine泄漏未读channel导致goroutine永久阻塞、死锁所有goroutine都在等待是常见陷阱。// 简单示例两个goroutine通过channel协作funcmain(){ch:make(chanstring)gofunc(){ch-done}()msg:-ch fmt.Println(msg)// 输出: done}goroutine 与操作系统线程OS thread的主要区别体现在调度方式、内存开销、创建成本、数量规模和抽象层级五个方面维度GoroutineGo 协程操作系统线程OS Thread调度器由 Go 运行时user-space scheduler调度M:N 多路复用M 个 goroutine 映射到 N 个 OS 线程由操作系统内核直接调度1:1 或 N:1 模型需陷入内核栈大小初始栈仅2KB按需动态增长/收缩最大可达几 MB通常固定且较大Linux 默认2MBWindows 约 1MB不可动态调整创建/销毁开销极低用户态分配少量元数据约几纳秒较高需内核参与clone()系统调用、分配栈、TLB/缓存刷新等微秒级可并发数量轻松支持数十万甚至百万级goroutine如 Web 服务器每请求一 goroutine受限于内存和内核资源数千线程即可能耗尽内存或触发 OOM抽象层级语言原生支持语法简洁go f()自动管理生命周期需调用系统 API如pthread_create手动管理同步、栈、退出等✅为什么更轻量核心原因用户态调度避免频繁的用户态/内核态切换上下文切换开销从微秒级降至纳秒级动态栈不预占大内存小栈起步 按需扩容空间利用率极高复用 OS 线程Go 运行时通过GMP 模型Goroutine, Machine/OS Thread, Processor/逻辑 P智能复用有限 OS 线程减少线程竞争与调度抖动。⚠️ 注意goroutine 并非“替代”线程而是更高层的抽象——它在底层仍依赖 OS 线程执行但对开发者屏蔽了复杂性实现“高并发易写高性能易得”。// 示例轻松启动 10 万个 goroutine实际可行内存占用约 200MB 左右fori:0;i100_000;i{gofunc(idint){// 每个 goroutine 初始仅占 ~2KB 栈空间fmt.Printf(Goroutine %d running\n,id)}(i)}