This is a creation in Article, where the information may have evolved or changed.
Today I have a problem (it should be a pit):
The defer close function of RPC is called when exiting in Goroutine, but the server always prompts the network to exit abnormally.
The final discovery is that goroutine call Close when exiting may cause blocking, blocking causes Goroutine to switch to main.
The program terminates after main exits.
I have constructed a similar example:
package mainimport ( "log" "time")func worker(quit <-chan bool) { defer func() { // 如果被调用函数内部可能阻塞的话 // 将不能保证被完全执行 time.Sleep(time.Second) log.Println("worker clean up") }() for { select { case <-quit: log.Println("worker quit ...") return default: } }}func main() { quit := make(chan bool) go worker(quit) quit <- true}
My current security practice is to set up a done pipeline, main blocking the function and waiting for the Goroutine cleanup to complete.
A better way to wait for Goroutine to complete is to use sync.WaitGroup :
"http://www.golang.org/",// using a WaitGroup to block until all the fetches are complete.func ExampleWaitGroup() { var wg sync.WaitGroup var urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/", } for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url) } // Wait for all HTTP fetches to complete. wg.Wait()}
For sync.WaitGroup Documentation Please refer to: http://golang.org/pkg/sync/#WaitGroup