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.

Reply via email to