Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go sync.Cond测试广播-为什么要检查循环?_Go_Synchronization_Goroutine - Fatal编程技术网

Go sync.Cond测试广播-为什么要检查循环?

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

我正在尝试使用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 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-在上述情况下),或是否有其他原因?