首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试go例程?

如何测试go例程?
EN

Stack Overflow用户
提问于 2013-09-23 09:08:20
回答 2查看 1.8K关注 0票数 2

当用户创建资源并删除资源时,就是这个问题的一个例子。我们将执行操作,并增加(减少)计数器缓存。

在测试中,有时会出现计数器缓存未被go例程更新的争用条件。

编辑:对不起,混淆了,澄清:计数器缓存不在内存中,它实际上是数据库中的一个字段。争用条件不是内存中的变量,实际上,goroutine写入数据库本身的速度可能很慢!

目前,我在操作后使用1秒睡眠,以确保在测试计数器缓存之前已经更新了计数器缓存。有没有另一种方法来测试go例程,而不需要任意1秒的睡眠等待go例程完成?

干杯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-23 14:36:24

在测试中,有时会出现计数器缓存未被go例程更新的争用条件。目前,我在操作后使用1秒睡眠,以确保在测试计数器缓存之前已经更新了计数器缓存。

唉,我不想说,但你做错了。Go有一流的特性使并发更容易!如果你正确使用它们,就不可能有比赛条件。

事实上,will 为你发现种族有一个工具。我敢打赌它会抱怨你的节目。

一个简单的解决方案:

  • 让主例程创建一个用于跟踪计数器的标线。
  • goroutine将只执行一个select,并得到一条消息来增加/减少或读取计数器。(如果读取,它将在一个通道中传递以返回数字)
  • 创建/删除资源时,通过它的通道向goroutine计数器发送适当的消息。
  • 当您想要读取计数器时,发送一条读取消息,然后读取返回通道。

(另一种选择是使用锁。这将是一个稍微更多的表现,但更麻烦的编写和确保它是正确的。)

票数 3
EN

Stack Overflow用户

发布于 2013-09-23 14:50:41

一种解决方案是让你的还盘提供一个一旦价值改变就被更新的通道。在go中,通过通信结果来实现同步是一种常见的做法。例如,您的Couter可能如下所示:

代码语言:javascript
复制
type Counter struct {
   value int
   ValueChange chan int
}

func (c *Counter) Change(n int) {
    c.value += n
    c.ValueChange <- c.value
}

每当调用Change时,新值将通过通道传递,等待该值的人将解除阻塞并继续执行,因此与计数器同步。使用此代码,您可以在ValueChange上侦听以下更改:

代码语言:javascript
复制
v := <-c.ValueChange

同时调用c.Change不再是问题了。

有一个游戏中的可运行示例

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18955498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档