Ian, Sorry to revive this old thread. Would it be possible to add your answer (and a solution with sync.Once suggested on this thread) to a FAQ and/or Effective Go document?
Yes, I stepped on it too trying to use close() as a signal that work is done, and then doing close() in a cleanup goroutine :) Thank you very much, Andrey On Wednesday, April 27, 2016 at 8:18:07 AM UTC-6, Ian Lance Taylor wrote: > > On Wed, Apr 27, 2016 at 6:52 AM, Alex Bligh <al...@alex.org.uk > <javascript:>> wrote: > > Closing a closed channel causes a panic - I know that. I'm interested in > why? > > > > I've seen (and written) lots of code that does > > > > func (x *X) Close() { > > x.mutex.Lock() > > defer x.mutex.Unlock() > > if !x.closed { > > x.closed = true > > close(x.chan) > > } > > } > > > > and have never seen a much simpler way to do it. A common reason is a > > 'done' signal on a chan struct{}. Yes I know you can use the context > > package, but that surely does something similar under the hood. > > > > Is there a good *reason* why closing a closed channel panics rather > > than does nothing? e.g. does making it safe add a lot of overhead? > > Closing a channel is a signal to the goroutine reading from the > channel that there are no more values to send. There should never be > any confusion as to whether there are more values to send or not. > Either you are done, and you close the channel, or you are not done, > and you do not close the channel. Closing a channel twice implies > that you don't know whether you are done or not. By that argument, > closing a channel twice does not make sense, so the runtime panics. > > It's true that there can be cases, especially when you aren't really > writing any values to the channel but are just using it as a > signalling mechanism, that you don't know whether you are done or not. > The current sense is that those cases are sufficiently rare that it's > appropriate to push the responsibility for the double close onto the > closer. Perhaps that should be rethought at some point, though not > for Go 1.7. The way to change this would be to make a proposal that > surveys some amount of Go code to see how much of it is (correctly) > checking for whether the channel has been closed before closing it. > If there is a lot of such code then perhaps the runtime should change > to silently ignore a close of a closed channel. > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.