当用户创建资源并删除资源时,就是这个问题的一个例子。我们将执行操作,并增加(减少)计数器缓存。
在测试中,有时会出现计数器缓存未被go例程更新的争用条件。
编辑:对不起,混淆了,澄清:计数器缓存不在内存中,它实际上是数据库中的一个字段。争用条件不是内存中的变量,实际上,goroutine写入数据库本身的速度可能很慢!
目前,我在操作后使用1秒睡眠,以确保在测试计数器缓存之前已经更新了计数器缓存。有没有另一种方法来测试go例程,而不需要任意1秒的睡眠等待go例程完成?
干杯
发布于 2013-09-23 14:36:24
在测试中,有时会出现计数器缓存未被go例程更新的争用条件。目前,我在操作后使用1秒睡眠,以确保在测试计数器缓存之前已经更新了计数器缓存。
唉,我不想说,但你做错了。Go有一流的特性使并发更容易!如果你正确使用它们,就不可能有比赛条件。
事实上,will 为你发现种族有一个工具。我敢打赌它会抱怨你的节目。
一个简单的解决方案:
(另一种选择是使用锁。这将是一个稍微更多的表现,但更麻烦的编写和确保它是正确的。)
发布于 2013-09-23 14:50:41
一种解决方案是让你的还盘提供一个一旦价值改变就被更新的通道。在go中,通过通信结果来实现同步是一种常见的做法。例如,您的Couter可能如下所示:
type Counter struct {
value int
ValueChange chan int
}
func (c *Counter) Change(n int) {
c.value += n
c.ValueChange <- c.value
}每当调用Change时,新值将通过通道传递,等待该值的人将解除阻塞并继续执行,因此与计数器同步。使用此代码,您可以在ValueChange上侦听以下更改:
v := <-c.ValueChange同时调用c.Change不再是问题了。
有一个游戏中的可运行示例。
https://stackoverflow.com/questions/18955498
复制相似问题