【发布时间】:2017-09-14 20:42:51
【问题描述】:
我使用 Go 已经有一段时间了,而且每天都在进步,但我本身并不是专家。目前我正在处理并发和 goroutines,因为我认为这是我的 Go 工具带中的最后一个未知数。我想我已经掌握了它的窍门,但仍然绝对是初学者。
我遇到的问题对我来说似乎很基本,但我尝试过的任何工作都没有。我想找出一种计算通道长度的方法。
根据我收集到的信息,len() 仅适用于缓冲通道,因此在这种情况下对我没有帮助。我正在做的是分批从数据库中读取值。我有一个生成器函数,就像
func gen() chan Result {
out := make(chan Result)
go func() {
... query db
for rows.Next() {
out <- row
}
close(out)
}()
return out
}
那么我就这样使用它
c := gen()
...
// do other stuff
我想用输出通道返回计数,或者将所有计数包装在一个结构类型中并返回它。
像这样:
c, len := gen()
或:
a := gen()
fmt.Println(a.c)
fmt.Println(a.len)
我相信除了使用 atomic 之外,我已经尝试了所有方法,我认为这实际上会起作用,但我阅读了周围,显然使用 atomic 不是正确的事情。我还有哪些其他选项不会让我留下 0 或无限阻塞
谢谢!
【问题讨论】:
-
你到底需要什么通道长度?
-
因为我在做批次的时候,最后一批的长度不会和其他批次一样。所以我在计算批次后所做的事情将需要它。因此,如果我有 89 行并且我按 10 个批次选择,最后一个将只有 9
-
您可以使用 sync/atomic 作为计数器,并在 for 循环的每次迭代中递增它,然后返回它。您的无缓冲通道没有“长度”;根据定义,它的长度始终为零。
-
你没有缓冲通道,但即使你有,缓冲通道的长度在并发发送或接收时也没有用,因为一旦你阅读它。
-
@Gavin 公平点。必须是存储在结构中的原子,并且您必须有一种方法知道批处理何时完成,然后才能读取它以获得权威计数。无论如何,对于原始问题,无缓冲通道没有长度。
标签: go concurrency channel