
下面代码中 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 3 天前 不会 |
2 YanSeven 3 天前 额,你这个 demo 不都已经写好了,go run 一下立马知道。 |
3 unused 3 天前 via Android 不会,但是不能保证 Do() 返回时 f() 已经执行 |
4 supuwoerc 3 天前 存在 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 3 天前 不会,但 if o.dOne== 1 { return } 存在 data race 。 |