Go sync.Cond测试广播-为什么要检查循环?
我正在尝试使用sync.Cond-Wait和Broadcast。我无法理解其中的某些部分: 等待电话的评论说:Go sync.Cond测试广播-为什么要检查循环?,go,synchronization,goroutine,Go,Synchronization,Goroutine,我正在尝试使用sync.Cond-Wait和Broadcast。我无法理解其中的某些部分: 等待电话的评论说: 41 // Because c.L is not locked when Wait first resumes, the caller 42 // typically cannot assume that the condition is true when 43 // Wait returns. Instead, the caller shoul
41 // Because c.L is not locked when Wait first resumes, the caller
42 // typically cannot assume that the condition is true when
43 // Wait returns. Instead, the caller should Wait in a loop:
44 //
45 // c.L.Lock()
46 // for !condition() {
47 // c.Wait()
48 // }
49 // ... make use of condition ...
50 // c.L.Unlock()
需要这样做的原因是什么
因此,这意味着以下程序可能不正确(尽管有效):
主程序包
进口(
“布菲奥”
“fmt”
“操作系统”
“同步”
)
类型处理器结构{
n int
同步秒
成龙国际酒店
}
func新处理器(n int)*处理器{
p:=新的(处理器)
p、 n=n
p、 c=sync.NewCond(&sync.Mutex{})
p、 started=制造(成交量,n)
返回p
}
func(p*处理器)启动(){
对于i:=0;i 条件变量不会保持信号状态,它们只会唤醒在.Wait()中阻塞的其他go例程。因此,除非您有一个谓词来检查您是否需要等待,或者您想要等待的事情是否已经发生,否则这将显示一个竞争条件
在您的特定情况下,在调用.Wait()
的go例程和调用.BroadCast()的go例程之间添加了同步
通过使用您的p.started
频道,以一种据我所知不应该呈现我在本文中进一步描述的比赛条件的方式。尽管我不会打赌,我个人只会按照文档中描述的惯用方式来做
假设您的start()
函数正在执行以下行中的广播:
p.c.L.Lock()
p.c.Broadcast()
在那个特定的时间点上,考虑到你的其他GO例程中的一个在你的<代码>过程()> /Cult>函数
中达到这一点。
fmt.Printf("fork : %d\n", f)
go例程要做的下一件事是锁定互斥体(至少在start()
中的go例程释放互斥体之前,它不会拥有互斥体)并等待条件变量
p.c.L.Lock()
p.started <- f
p.c.Wait()
p.c.L.锁()
p、 started条件变量不会保持信号状态,它们只会唤醒在.Wait()中阻塞的其他go例程。因此,除非您有一个谓词,在该谓词中检查是否需要等待,或者您想要等待的事情是否已经发生,否则这将显示一个竞争条件
在您的特定情况下,在调用.Wait()
的go例程和调用.BroadCast()的go例程之间添加了同步
通过使用您的p.started
频道,以一种据我所知不应该呈现我在本文中进一步描述的比赛条件的方式。尽管我不会打赌,我个人只会按照文档中描述的惯用方式来做
假设您的start()
函数正在执行以下行中的广播:
p.c.L.Lock()
p.c.Broadcast()
在那个特定的时间点上,考虑到你的其他GO例程中的一个在你的<代码>过程()> /Cult>函数
中达到这一点。
fmt.Printf("fork : %d\n", f)
go例程要做的下一件事是锁定互斥体(至少在start()
中的go例程释放互斥体之前,它不会拥有互斥体)并等待条件变量
p.c.L.Lock()
p.started <- f
p.c.Wait()
p.c.L.锁()
p、 首先,我假设您正在谈论第二次检查awake
(在循环中完成的检查)。第一次检查显然是为了检查c.Wait()
是否等待广播这里是关于提交的codereview讨论,介绍了这段代码:@HectorJ为什么代码需要检查c.Wait())你在等广播吗?这不是C.等广播的本意吗?这是本意,所以需要测试。@HectorJ明白了,我重新表述了我的问题。我假设你在谈论第二次检查唤醒(循环中完成的那次)。第一次检查显然是来检查C.等()
did wait for broadcast下面是介绍此代码的提交的codereview讨论:@HectorJ为什么代码需要检查c.wait()是否正确是否等待广播?这不是C.等待广播的意图吗?这是意图,因此需要进行测试。@HectorJ明白了,我已重新表述了我的问题。谢谢,在代码中,“开始”函数等待所有的“n”go例程在广播之前开始执行。因此,go例程开始执行且信号已广播的情况不会发生?在其他情况下,可能需要对p.done进行测试,但情况并非如此?等待和广播是否也要求调用方锁定以解锁,只是为了启用对条件变量(p.done-在上面的例子中),或者还有其他原因吗?谢谢,在代码中“start”函数等待所有的“n”go例程在广播之前开始执行。因此,go例程开始执行且信号已广播的情况不会发生?在其他情况下,可能需要对p.done进行测试,但情况并非如此?等待和广播是否也要求调用方锁定以解锁,只是为了启用对条件变量(p.done-在上述情况下),或是否有其他原因?