所以,现在,我只是传递一个指向 Queue 对象的指针(实现并不重要),并queue.add(result)
在应该向队列中添加内容的 goroutines 结束时调用。
我需要同样的功能——当然,与简单的队列添加函数调用相比,使用逗号 ok 语法进行循环检查完成在性能方面是不可接受的。
有没有办法更好地做到这一点?
您的问题实际上有两个部分:一个如何在 Go 中排队数据,一个如何在不阻塞的情况下使用通道。
对于第一部分,听起来您需要做的不是使用通道将内容添加到队列中,而是将通道用作队列。例如:
var (
ch = make(chan int) // You can add an int parameter to this make call to create a buffered channel
// Do not buffer these channels!
gFinished = make(chan bool)
processFinished = make(chan bool)
)
func f() {
go g()
for {
// send values over ch here...
}
<-gFinished
close(ch)
}
func g() {
// create more expensive objects...
gFinished <- true
}
func processObjects() {
for val := range ch {
// Process each val here
}
processFinished <- true
}
func main() {
go processObjects()
f()
<-processFinished
}
至于如何使这更加异步,您可以(正如 cthom06 指出的那样)将第二个整数传递给make
第二行中的调用,这将使发送操作异步,直到通道的缓冲区已满。
编辑:但是(正如 cthom06 也指出的那样),因为您有两个 goroutine 写入通道,其中一个必须负责关闭通道。此外,我之前的修订版将在 processObjects 完成之前退出。我选择同步 goroutine 的方式是创建更多通道来传递虚拟值,以确保清理正确完成。这些通道是专门无缓冲的,因此发送发生在锁步中。