下面代码中 f()会被重复执行吗?
package main
import (
"fmt"
"sync"
)
type Once struct {
m sync.Mutex
done uint32
}
func (o *Once) Do(f func()) {
if o.done == 1 {
return
}
o.m.Lock()
defer o.m.Unlock()
fmt.Println("bing: ", o.done)
if o.done == 0 {
o.done = 1
f()
}
}
func main() {
var once Once
wg := sync.WaitGroup{}
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
once.Do(func() {
println("executed---------》 ")
})
}()
}
wg.Wait()
}
1
ccpp132 1 天前
不会
|
2
YanSeven 1 天前
额,你这个 demo 不都已经写好了,go run 一下立马知道。
|
3
unused 1 天前 via Android
不会,但是不能保证 Do() 返回时 f() 已经执行
|
4
supuwoerc 14 小时 19 分钟前
存在 data race ,你想要双重检查标识位,但是第一次检查没在加锁之后,是存在潜在问题的。
问题出现在 done uint32 的读写并不是原子的,你需要换成原子读写,你这段代码和 sync.Once 的区别就是这里。 ``` func (o *Once) Do(f func()) { if atomic.LoadUint32(&o.done) == 1 { return } o.m.Lock() defer o.m.Unlock() fmt.Println("bing: ", o.done) if atomic.LoadUint32(&o.done) == 0 { atomic.StoreUint32(&o.done, 1) f() } } ``` |
5
bv 14 小时 18 分钟前
不会,但 if o.done == 1 { return } 存在 data race 。
|