可以把一个频道保持开放吗?

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

Is it OK to leave a channel open?

问题

如果我从不检查通道的状态,永远不关闭通道,这样做可以吗?这会导致内存泄漏吗?以下代码可以吗?

func (requestCh chan<- Request) GetResponse(data RequestData) Response {
    reply := make(chan Response)
    requestCh <- Request{data: data, replyCh: reply}
    return <-reply
}
英文:

Is it OK to leave a Go channel open forever (never close the channel) if I never check for its state? Will it lead to memory leaks? Is the following code OK?

func (requestCh chan<- Request) GetResponse(data RequestData) Response {
    reply := make(chan Response)
    requestCh <- Request{data: data, replyCh: reply}
    return <-reply
}

答案1

得分: 401

可以永远保持一个Go通道开放而不关闭它。当通道不再使用时,它将被垃圾回收。

请注意,只有在接收器正在寻找关闭时才需要关闭通道。关闭通道是通道上的控制信号,表示没有更多的数据。

英文:

It's OK to leave a Go channel open forever and never close it. When the channel is no longer used, it will be garbage collected.

> Note that it is only necessary to close a channel if the receiver is
> looking for a close. Closing the channel is a control signal on the
> channel indicating that no more data follows.
>
> Design Question: Channel Closing

答案2

得分: 60

是的,保持一个通道开放是可以的。正如《Go编程语言》一书所述:

> 当你完成对通道的使用时,不需要关闭每个通道。只有在重要的情况下需要关闭通道,以告知接收的goroutine所有数据已发送完毕。垃圾回收器确定不可达的通道将会回收其资源,无论是否关闭。(不要将此与打开文件的关闭操作混淆。当你完成对每个文件的使用时,调用Close方法非常重要。)

英文:

Yes, it is ok to keep a channel open. As the go programming language book stated:

> You needn't close every channel when you've finished with it. It's
> only necessary to close a channel when it is important to tell the
> receiving goroutines that all data have been sent.
A channel that the
> garbage collector determinies to be unreachable will have its
> resources reclaimed whether or not it is closed. (Don't confuse this
> with the close operation for open files. It is important to call the
> Close method on every file when you've finished with it.)

答案3

得分: 10

是的,将通道保持打开是可以的,实际上这是典型的做法。通道保持打开并不意味着对通道对象的引用,因此不会阻止其被垃圾回收。

英文:

Yes, it's OK to leave the channel open, and in fact it is typical. A channel being open does not constitute a reference to the channel object, and so does not keep it from being garbage collected.

答案4

得分: 9

"使用Go通道的一个通用原则是,不要从接收方关闭通道,也不要在通道有多个并发发送方时关闭通道。

如上所述,一旦通道被标记为清理,它最终会被垃圾回收,所以不关闭通道是可以的,唯一的区别是通道可能在几个循环后才会被gc回收,如果没有显式关闭。

此外,以下文章这里这里展示了在1:N、N:1或M:N(发送方:接收方)情况下关闭通道的各种方法。

英文:

"One general principle of using Go channels is don't close a channel from the receiver side and don't close a channel if the channel has multiple concurrent senders."

As clearly mentioned in answer above that every channel will be GCed eventually once it is marked for cleanup, so it is okay to leave channel un-closed the only difference it will make is that that channel will be available for gc after a few cycles maybe if not closed explicitly.

Also the following articles this and this shows various ways to close a channel in case of 1:N, N:1 or M:N (senders:receivers)

答案5

得分: 8

这在上面已经很好地解释了,但是我发现A Tour of Go中的以下内容非常清晰,它还提供了一个close的示例:

另一个注意事项: 通道不像文件;通常不需要关闭它们。只有在接收方必须被告知没有更多的值到来时,例如终止range循环时,才需要关闭通道。

英文:

This is very well covered above, however I find the following from A Tour of Go very clear, which also gives an example of when to close:

> Another note: Channels aren't like files; you don't usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop.

答案6

得分: 1

这不总是可以的。保持一个通道开放可能会导致内存泄漏,这取决于你如何编写代码。

尽管Go有垃圾回收机制,但如果一个使用通道的Goroutine因某种原因被阻塞(保持通道开放可能是Goroutine被阻塞的原因之一),就会导致内存泄漏。

这是一篇关于通道、Goroutine以及它们与Golang中大多数内存泄漏问题相关的好文章。

https://betterprogramming.pub/common-goroutine-leaks-that-you-should-avoid-fe12d12d6ee

英文:

It's not always OK. Leaving a channel open can cause memory leaks, depending on how you coded it.

Although GO is garbage collected, if a Goroutine that uses a channel for some reason is blocked (and leaving a channel open can be one of the reasons to the goroutine stay blocked), you will have a memory leak.

Here is a good article about the use of channels, goroutines, and how they are associated with most memory leaks problems in golang.

https://betterprogramming.pub/common-goroutine-leaks-that-you-should-avoid-fe12d12d6ee

答案7

得分: 0

Go是有垃圾回收的,所以你不需要真正地“释放”任何东西。

关闭通道是可能的,但它主要用于 - close(channel) - 告诉goroutine(或主程序)在该通道上不会再发送任何其他内容。

英文:

Go is garbage collected, so you don't really have to 'free' anything.

There is possibility to close channels, but it's mostly used as - close(channel) - tell the goroutine (or main program) that nothing else will be sent on that channel.

答案8

得分: -2

如果您手动关闭通道,您将节省一些垃圾收集器的任务,从而节省一些计算资源,并稍微加快程序的运行速度。

英文:

If you will manually close the channel you are saving some task of garbage collector so saving some compute and speeding up your program a little bit.

huangapple
  • 本文由 发表于 2011年12月22日 01:12:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/8593645.html
匿名

发表评论

匿名网友

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

确定