在完成时将通道结果添加到队列的更惯用的方法

时间:2010-06-28 03:45:21

标签: go channel goroutine

所以,现在,我只是传递一个指向Queue对象的指针(实现并不重要),并在goroutine的末尾调用queue.add(result),这应该将东西添加到队列中。

我需要相同类型的功能 - 当然,使用逗号ok语法进行循环检查完成在性能方面与简单队列添加函数调用相比是不可接受的。

有没有办法更好地做到这一点?

1 个答案:

答案 0 :(得分:1)

您的问题实际上有两个部分:如何在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也指出的那样),因为你有两个goroutines写入频道,其中一个必须负责关闭频道。此外,我的先前版本将在processObjects完成之前退出。我选择同步goroutine的方法是创建几个传递虚拟值的通道,以确保清理正确完成。这些通道是专门无缓冲的,因此发送是锁定步骤。