一、Happens-Before 原则1.1 什么是 Happens-BeforeHappens-Before 是 Go 内存模型的核心概念,定义了操作之间的可见性顺序。如果操作 A “happens-before” 操作 B,那么 A 的结果对 B 可见。var x int funcmain(){x=1// 操作 A fmt.Println(x)// 操作 B - 能看到x=1}1.2 Go 中的 Happens-Before 规则1.2.1 单线程规则:在单个 goroutine 中,操作按程序顺序发生funcsingleGoroutine(){a :=1//1b :=a +1//2- 能看到a=1c :=b *2//3- 能看到b=2}1.2.2 Channel 规则:Channel 操作创建 happens-before 关系funcchannelHB(){var c=make(chan int,1)var data string // Goroutine1gofunc(){data="Codee君"//1c-1//2- 发送}()-c //3- 接收 happens-after 发送 fmt.Println(data)//4- 保证能看到"Codee君"}1.2.3 Mutex/RWMutex 规则:互斥锁解锁 happens-before 后续加锁funcmutexHB(){var mu sync.Mutex var data int // Goroutine1gofunc(){mu.Lock()//1data=42//2mu.Unlock()//3- 解锁}()mu.Lock()//4- 发生在解锁之后 fmt.Println(data)//5- 保证能看到42mu.Unlock()}1.2.4 Once 规则:sync.Once.Do() 调用 happens-after 所有之前对 Do() 的调用返回funconceHB(){var once sync.Once var data string // setup 只会执行一次 setup :=func(){data="initialized"}// 多个 goroutine 同时调用fori :=0;i10;i++{gofunc(){once.Do(setup)//1- 所有调用都会看到 setup 的结果 fmt.Println(data)}()}}1.2.5 WaitGroup 规则:Wait() 返回 happens-after 所有 Add() 调用funcwaitGroupHB(){var wg sync.WaitGroup var results[]intfori :=0