一、前言Go 语言的核心优势 —— 原生并发Go 被称为21 世纪的 C 语言两大核心亮点语法设计简洁、上手门槛低语言层面原生支持并发内置 GC 自动垃圾回收无需手动管理内存Go 并发设计哲学不同于传统多线程靠锁实现同步Go 采用通信的方式解决并发竞争不要通过共享内存来通信而要通过通信来共享内存二、基础概念并发 vs 并行1. 并行Parallelism同一时刻多条指令在不同 CPU 核心同时执行必须依赖多核硬件。2. 并发Concurrency同一时刻只有一条指令在 CPU 执行系统通过时间片轮转快速切换多个任务宏观看起来多个任务同时运行微观是交替执行单核 CPU 即可实现。举例单核 CPU 处理 3 个 1s 任务靠时间片切换实现并发在有限硬件资源下提升整体处理效率。核心区分总结并发同时处理多件事单核、任务切换并行同时做多件事多核、真正同时执行三、Goroutine协程Go 并发核心1. 什么是 GoroutineGoroutine 是 Go 内置的轻量级协程可简单理解为轻量任务是 Go 并行调度的核心比操作系统线程体积更小、开销极低底层采用 M:N 调度成千上万个 goroutine 会复用少量 OS 线程Go 运行时自动管理 goroutine 内存共享调度成本远低于线程优势易用、高效、资源占用极少。2. 创建 Goroutine语法在函数 / 匿名函数前加go关键字即可新建子协程。go// 普通函数开启协程 go newTask() // 匿名函数协程必须加()执行 go func() { // 协程业务逻辑 }()3. 核心规则主协程退出所有子协程直接销毁main函数本身是主协程一旦 main 执行完毕整个进程直接终止所有未执行完成的子协程会被强制杀死不会等待。示例 1子协程来不及执行gopackage main import time func newTask() { for { fmt.Println(子协程运行中) time.Sleep(time.Second) } } func main() { // 开启子协程 go newTask() // 主协程循环2次就退出 i : 0 for { i fmt.Println(主协程 i , i) time.Sleep(time.Second) if i 2 { break // main结束子协程直接销毁无任何输出 } } }示例 2死循环阻塞主协程测试用写无限for{}阻塞主协程防止程序提前退出方便观察子协程输出gofunc main() { go newTask() // 死循环阻塞主线程 for {} }四、runtime 包协程调度控制工具1. runtime.Gosched ()主动让出 CPU 时间片作用当前 goroutine 主动放弃执行权调度器切换其他就绪协程运行等其他协程执行完毕后再切回当前协程。示例不加 Gosched 时主协程会优先跑完子协程无执行机会gopackage main import ( fmt runtime ) func main() { go func() { for i : 0; i 5; i { fmt.Println(子协程 go) } }() for i : 0; i 2; i { fmt.Println(主协程 hello) runtime.Gosched() // 主动让出时间片让子协程先执行 } }2. runtime.Goexit ()终止当前协程作用立即结束当前所在 goroutine不会影响其他协程会优先执行当前协程所有 defer 延迟函数普通return仅终止当前函数不会退出协程。gopackage main import ( fmt runtime ) func test() { defer fmt.Println(执行defer延迟语句) // runtime.Goexit() // 终止整个子协程 return // 仅退出test函数协程继续往下执行 fmt.Println(该行永远不会打印) } func main() { go func() { fmt.Println(子协程开始) test() fmt.Println(子协程结束) // Goexit()时该行不会执行 }() // 死循环阻塞主协程 for {} }3. runtime.GOMAXPROCS (n)设置并行 CPU 核心上限功能设置可并行执行 goroutine 的 OS 线程最大数量返回修改前的旧值规则n1单核运行无真正并行仅时间片切换并发n 等于 CPU 物理核数最大化多核并行能力Go1.5 默认值为机器 CPU 核心数效果核数越大多协程交替输出越混乱并行效率越高。gopackage main import ( fmt runtime ) func main() { // 设置仅使用1核CPU返回旧配置 old : runtime.GOMAXPROCS(1) fmt.Println(修改前CPU并行数, old) for { go fmt.Print(1) fmt.Print(0) } }五、多协程资源竞争问题场景模拟多个协程共用同一个打印机公共资源多个 goroutine 同时操作同一共享资源会出现输出错乱、数据混乱即并发竞争需要同步机制解决。gopackage main import fmt // 公共打印机资源 func Printer(str string) { for _, data : range str { fmt.Print(string(data)) } fmt.Println() } func person1() { Printer(hello) } func person2() { Printer(world) } func main() { // 两个协程同时抢占打印机输出错乱 go person1() go person2() // 阻塞主协程观察效果 for {} }解决方案预告Go 官方推荐使用channel 通道实现 goroutine 同步与通信解决资源竞争下一章详细讲解。六、全文总结面试 / 复习速记Go 核心优势语言原生并发goroutine 轻量高效GC 自动回收并发单核时间片切换并行多核同时执行goroutine 创建go 函数主协程退出则所有子协程销毁runtime 三大工具Gosched()主动让出 CPUGoexit()终止当前协程执行 deferGOMAXPROCS()控制并行 CPU 核心数多协程访问公共资源会产生竞争使用 channel 通信实现同步。