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

发布于 2024-09-07 10:12:48 字数 195 浏览 4 评论 0原文

因此,现在,我只需传递一个指向 Queue 对象的指针(实现并不重要),并在 goroutine 末尾调用 queue.add(result) 来将内容添加到队列中。

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

有没有办法做得更好,或者没有?

So, right now, I just pass a pointer to a Queue object (implementation doesn't really matter) and call queue.add(result) at the end of goroutines that should add things to the queue.

I need that same sort of functionality—and of course doing a loop checking completion with the comma ok syntax is unacceptable in terms of performance versus the simple queue add function call.

Is there a way to do this better, or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零度℉ 2024-09-14 10:12:48

您的问题实际上有两个部分:如何在 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 的方法是创建更多的通道来传递虚拟值,以确保清理正确完成。这些通道专门是无缓冲的,因此发送是同步进行的。

There are actually two parts to your question: how does one queue data in Go, and how does one use a channel without blocking.

For the first part, it sounds like what you need to do is instead of using the channel to add things to the queue, use the channel as a queue. For example:

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
}

As for how you can make this more asynchronous, you can (as cthom06 pointed out) pass a second integer to the make call in the second line which will make send operations asynchronous until the channel's buffer is full.

EDIT: However (as cthom06 also pointed out), because you have two goroutines writing to the channel, one of them has to be responsible for closing the channel. Also, my previous revision would exit before processObjects could complete. The way I chose to synchronize the goroutines is by creating a couple more channels that pass around dummy values to ensure that the cleanup gets finished properly. Those channels are specifically unbuffered so that the sends happen in lock-step.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文