简体   繁体   中英

Is it possible to safely close a channel once from multiple goroutines using select?

My solution would be as follows, but is there a race condition in the following code (will it ever panic)?

c := make(chan struct{})

for i := 0; i < 1000000; i++ {
    go func() {
        select {
        case <-c:
        default:
            close(c)
        }
    }()
}

I would assume yes, but go test -race doesn't detect it and empirically I couldn't get it to panic.

You launch multiple goroutines without synchronization. So they run concurrently. It may happen 2 of them evaluates <-c in parallel, seeing it's a blocking operation, so both will choose the default case. At that point, both of those 2 goroutines will try to close the channel, and only one of them will succeed, the other will panic: you can't close a closed channel.

This is not a race condition because you don't read/modify variables concurrently, but attempting to close a closed channel is a runtime panic (so the race detector will never catch this).

When there are multiple goroutines sending on a channel, wait for all to complete and then close the channel in a single goroutine. Do not attempt to close a channel from multiple goroutines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM