多个线程并发执行计数时,给临界区加锁进行数据保护
代码示例: 开10个协程 每个协程将计数器进行10万次的 加一操作。我们理想的状况是计数器最终是100万。(不加排他锁,则计数器数据会因为并发出现不是我们需要的结果)
package main
import (
"fmt"
"sync"
)
// 开启10个协程 每个协程改写变量10万次,但是运行程序在不加互斥锁的情况下,变量得到的结果不是100万
// 需要知道并发修改公共资源的临界区在哪,在临界区加锁
func main() {
var count = 0 //公共修改的变量
var mu = sync.Mutex{}
//使用WaitGroup等待10个goroutine完成
var wg sync.WaitGroup
wg.Add(10) //添加10个等待
//循环执行10个协程
for i := 0; i < 10; i++ {
go func() {
defer wg.Done() //执行完一个协程去掉一个等待
//对count进行10万次加1
for j := 0; j < 100000; j++ {
//开始执行到临界区域 加锁
mu.Lock()
count++ //此处为临界区域
//临界区域执行结束 释放锁
mu.Unlock()
}
}()
}
//主线程等待10个协程完成
wg.Wait()
fmt.Println(count)
}
如上示例中:
1.WaitGgroup 保证了主线程等待10个协程执行完后才结束
2.Mutex保证了 count计数器每一时刻只有一个协程在修改