I've implemented a method to shutdown my server by closing a channel, so other goroutines read the closed channel then exit. After the shutdown, I need to do some cleaning with server data, if close()
blocks until all other goroutines read the closed channel, I can access the data without lock. So the question is: does closing a channel block until the receiver read from it? Below is the example code:
package main
type server struct {
chStop chan struct{}
data map[int]interface{}
}
func newServer() *server {
return &server {
chStop: make(chan struct{})
}
}
func (s *server) stop() {
close(s.chStop)
// do something with s.data
...
// if other goroutines already read closed s.chStop and exited,
// we can access s.data without lock
}
func (s *server) run2() {
...
for {
select{
case <-s.chStop:
return
case <- other channel:
// access s.data with lock
}
}
}
func (s *server) run() {
ch := make(chan struct{})
...
for {
select{
case <-s.chStop:
return
case <- ch:
// access s.data with lock
}
}
}
func main() {
s := newServer()
go s.run()
go s.run2()
s.stop()
}
No. Use a sync.WaitGroup
instead.