代码实现
package main
import (
"fmt"
"sync"
)
var (
dataSlice []int
mu sync.Mutex
wg sync.WaitGroup
)
func writeData(num int) {
defer wg.Done()
mu.Lock()
dataSlice = append(dataSlice, num)
mu.Unlock()
}
func readData() {
defer wg.Done()
mu.Lock()
for _, v := range dataSlice {
fmt.Println(v)
}
mu.Unlock()
}
func main() {
// 模拟并发写操作
for i := 0; i < 10; i++ {
wg.Add(1)
go writeData(i)
}
// 等待所有写操作完成
wg.Wait()
// 模拟并发读操作
wg.Add(1)
go readData()
// 等待读操作完成
wg.Wait()
}
实现原理
- Mutex:使用
sync.Mutex
来保护对dataSlice
的读写操作。在写操作writeData
和读操作readData
中,首先通过mu.Lock()
加锁,这样在同一时间只有一个goroutine能够访问dataSlice
,防止多个goroutine同时读写导致数据竞争。操作完成后,通过mu.Unlock()
解锁,允许其他goroutine进行操作。
- WaitGroup:使用
sync.WaitGroup
来同步goroutine。在启动每个写操作的goroutine前,通过wg.Add(1)
增加等待组的计数。在写操作完成后,通过wg.Done()
减少计数。在主函数中,使用wg.Wait()
等待所有写操作完成后再进行读操作,确保读操作能读取到完整的数据。同样,在启动读操作的goroutine前也增加计数,读操作完成后减少计数,以确保主函数等待所有操作完成后再退出。