2 回答
TA贡献1995条经验 获得超2个赞
问题是,在任何一个调用中都不能保证在之前运行;甚至你的原始代码的使用也不能保证它(因为它是重要的部分,而不是goroutine的生成)c.Wait()button.Clicked.Broadcast()WaitGroupc.Wait()
修改订阅:
subscribe := func(c *sync.Cond, subWG *sync.WaitGroup, fn func()) {
go func() {
c.L.Lock()
defer c.L.Unlock()
subWG.Done() // [2]
c.Wait()
fn()
}()
}
等待代码:
subWG.Done()
button.Clicked.L.Lock()
button.Clicked.L.Unlock()
这是基于这样的观察,这种观察只能在开始时发生,或者发生在所有先前执行的goroutines都坚持之后,由于它们共享的储物柜。因此,这意味着(或订阅数量)被执行,只有一个goroutine没有坚持下去,这可以通过要求将储物柜到另一个时间来解决。[2][2]c.WaitsubWG.Wait()2[2]c.WaitLock
游乐场: https://play.golang.org/p/6mjUEcn3ec5
TA贡献1942条经验 获得超3个赞
使用等待组(在当前组中编码):当函数返回时,您知道等待的goroutine至少已经开始执行。wg
subscribe
因此,当您的主要功能达到时,很有可能两个goroutine实际上正在等待他们的呼叫。button.Clicked.Broadcast()
button.Clicked.Wait()
如果没有 ,则无法保证 goroutines 甚至已启动,并且您的代码可能调用得太快。wg
button.Clicked.Broadcast()
请注意,使用 它只是降低了死锁发生的可能性,但它不会在所有情况下阻止死锁。wg
尝试编译你的二进制文件,并在循环中运行它(例如从bash :),我想你会看到同样的问题有时会发生。-race
for i in {1..100}; do ./myprogram; done
- 2 回答
- 0 关注
- 67 浏览
添加回答
举报