【发布时间】:2021-03-03 02:24:27
【问题描述】:
func main() {
var wg sync.WaitGroup
ch := make(chan int,5)
start:= time.Now()
cnt:=0
wg.Add(10000)
for i:=0; i<10000; i++ {
ch <- 1
go func() {
defer wg.Done()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
这里我想同时执行程序,并且我希望最多有 5 个 goroutine。 问题是当我打印出“cnt”时,它不会是 10000。这意味着我有一些未执行的 goroutine。我该如何解决这个问题?
现在我正在使用互斥锁来解决问题,但是这个程序的运行时间不会因为 goroutine 而更好,我不明白为什么。
func main() {
var wg sync.WaitGroup
var mutex sync.Mutex
ch := make(chan int,5)
start:= time.Now()
cnt:=0
for i:=0; i<10000; i++ {
wg.Add(1)
ch <- 1
go func() {
defer wg.Done()
defer mutex.Unlock()
mutex.Lock()
doSomething()
cnt++
<-ch
}()
}
wg.Wait()
fmt.Println(cnt)
end:= time.Now()
fmt.Println("End of program.",end.Sub(start))
}
【问题讨论】:
-
你有一个数据竞赛。结果毫无意义。
-
你在那里操作一个变量并且在并发期间它是不安全的,尝试在变量和
wg.add(1)循环之间使用sycn.Mutex -
使用互斥锁保护
cnt++。 -
您更新的代码现在在 Goroutine 开始时锁定一个互斥锁,并在完成后解锁它;这将阻止并发执行。如果
doSomething()是线程安全的,那么您只需要在cnt++周围保持锁定,即mutex.Lock(); cnt++; mutex.Unlock()
标签: go concurrency goroutine