package main
import (
"fmt"
"sync"
)
func main() {
data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var wg sync.WaitGroup
var mu sync.Mutex
results := make([]int, 0)
numCoroutines := 3
chunkSize := (len(data) + numCoroutines - 1) / numCoroutines
for i := 0; i < numCoroutines; i++ {
start := i * chunkSize
end := (i + 1) * chunkSize
if end > len(data) {
end = len(data)
}
wg.Add(1)
go func(s, e int) {
defer wg.Done()
localResult := 0
for _, v := range data[s:e] {
localResult += v
}
mu.Lock()
results = append(results, localResult)
mu.Unlock()
}(start, end)
}
wg.Wait()
fmt.Println("Final results:", results)
}
同步工具的作用
- WaitGroup:
wg
是 sync.WaitGroup
类型的变量。
wg.Add(1)
用于通知 WaitGroup
有一个新的协程开始工作,这里每启动一个协程就调用一次 Add(1)
。
defer wg.Done()
表示当前协程工作完成,会减少 WaitGroup
的计数。
wg.Wait()
会阻塞当前 goroutine,直到 WaitGroup
的计数归零,即所有协程都调用了 Done()
,确保所有协程处理完成后才进行后续操作。
- Mutex:
mu
是 sync.Mutex
类型的变量。
mu.Lock()
用于锁定互斥锁,防止其他协程同时访问共享资源 results
。
mu.Unlock()
用于解锁互斥锁,允许其他协程访问共享资源 results
。这样就避免了多个协程同时写入 results
导致的数据竞争问题。