Golang通道维护

3

我使用go channel作为类似队列的机制,这个方式非常适合我。我为每个用户打开一个这样的队列式通道,并为每个通道都有一个for-range循环。唯一的问题是我没有关闭任何这些通道。

我想知道在Go中是否习惯于运行一个基于计时器的go协程,以销毁不活动的通道,几乎像“智能”垃圾收集器一样。

任何反馈将不胜感激。

谢谢。


在Go中,您不需要关闭通道,它们不像Unix文件描述符或类似的东西。我不知道这是否是您要问的,但我想指出这一点。 - Eric Urban
1个回答

3

通常情况下,在通道读写时都会设置超时时间。这是一种保障措施,确保Go例程如果经过一定的时间仍未返回结果,则停止阻塞。

一个使用案例是,您启动了N个例程以对各种HTTP客户端执行异步搜索。您希望尽可能多地等待结果,但又不希望永远等待。这些HTTP获取器将执行其查询并将结果发送回给您,前提是他们可以在指定的超时时间内完成任务。

以下是该原则的简单版本。您可以在Go playground上运行它。唯一区别是这里的Go例程正在从我们的队列通道中读取,而不是发送数据给我们。但原则是相同的。

package main

import (
    "fmt"
    "time"
)

func main() {
    queue := make(chan int, 1)
    defer close(queue)

    // Fire up a consumer.
    // Ensure it times out after 3 seconds of waiting for a value.
    go func() {
        select {
        case val := <-queue:
            fmt.Printf("Received: %d\n", val)
        case <-time.After(3 * time.Second):
            fmt.Println("Timeout!")
        }
    }()

    // Do something important for 5 seconds.
    <-time.After(5 * time.Second)

    // Send value to user.
    queue <- 123
}

1
这不是一个很好的例子。main()函数可能会在你的goroutine到达Print{f,ln}语句之前就结束/关闭(从而结束程序)。通常情况下,您应该在goroutine中执行“工作”,并在生成(主)函数中等待结果。 - mzimmerman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接