Golang通道维护

huangapple go评论78阅读模式
英文:

Golang Channel Maintenance

问题

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

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

任何反馈都将不胜感激。

谢谢。

英文:

I'm using go channels as a queue-like mechanism, which has suited me very well. I'm opening up one of these queue-like channels for each user, and have a for-range loop for each one of these channels. The only thing is that I'm not closing any of these channels.

I was wondering if its customary in Go to run a go-routine on a timer that basically destructs inactive channels, almost acting like a "smart" garbage collector.

Any feedback would be appreciated.

Thanks.

答案1

得分: 3

给通道的读取和写入设置超时是一种常见的做法。这是一种保护措施,确保在给定的时间间隔内,goroutine停止阻塞。

一个使用场景是,你启动N个goroutine在各个HTTP客户端上执行异步搜索。你希望尽可能多地等待结果,但又不想永远等待。这些HTTP获取器将执行它们的查询并将结果发送回给你,前提是它们能够在设定的超时时间内完成任务。

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

package main

import (
	"fmt"
	"time"
)

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

	// 启动一个消费者。
	// 确保在等待值的过程中超时时间为3秒。
	go func() {
		select {
		case val := <-queue:
			fmt.Printf("Received: %d\n", val)
		case <-time.After(3 * time.Second):
			fmt.Println("Timeout!")
		}
	}()

	// 做一些重要的事情,持续5秒。
	<-time.After(5 * time.Second)

	// 发送值给用户。
	queue <- 123
}

希望对你有帮助!

英文:

It is a common practice to furnish channel reads and writes with a timeout. This is a safeguard which ensures a goroutine stops blocking if a given interval of time has passed.

A use case for this is where you fire up N routines to perform asynchronous searches on various http clients. You will want to wait for results from as many as you can, but you don't want to wait forever. These http fetchers will perform their query and send the result back to you, provided they can accomplish the task within a set timeout.

Here is a simple version of that principle. You can run it on the Go playground. The only difference here is that the goroutine
is reading from our queue channel, instead of being the one to send us data. But the principle is identical.

package main

import (
    &quot;fmt&quot;
    &quot;time&quot;
)

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 := &lt;-queue:
		    fmt.Printf(&quot;Received: %d\n&quot;, val)
	    case &lt;-time.After(3 * time.Second):
		    fmt.Println(&quot;Timeout!&quot;)
	    }
    }()

    // Do something important for 5 seconds.
    &lt;-time.After(5 * time.Second)

    // Send value to user.
    queue &lt;- 123
}

huangapple
  • 本文由 发表于 2014年2月24日 09:07:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/21977110.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定