A recent online module has a memory leak, added HTTP pprof, found that Goroutine has been growing, suspected goroutine leakage caused by memory leaks. Then die looking at the code and find that the following code fragment may have a problem:
Goroutine ...
for{
Select {Case
...
...
case ... ...
Case <-Exitchan: Break
;
}
}
Code logic, when the socket is closed to send data to Exitchan, this time the goroutine in the above code needs to jump out for loop, end the Goroutine.
The problem is in the break, where the break is out of case, or out of for? Select-case no break, so I should be writing code when I thought this break would jump out for loop. Not sure, then write a code to test it.
Package main
Import (
"FMT"
"Time"
)
var Exitchan chan bool
func Waiting1 () {defer func
() {
FMT. Println ("Waiting1 exit")
} ()
//do someting time
. Sleep (time. Second *10)
Exitchan <-True
}
func Waiting2 () {defer func
() {FMT
. Println ("Waiting2 exit")
} ()
for{
Select {Case
<-time. After (time). Second * 2):
FMT. PRINTLN ("Tick event ...") Case
<-Exitchan:
fmt. Println ("Exit event ...") Break}
}
func main () {
Exitchan = make (chan bool)
go Waiting1 () Go
Waiting2 ()
<-time. After (time). Second *)
FMT. Println ("main return")
}
The results tell me that the break in Select-case just jumped out of the select Branch, like the switch-case in C language. But in C, you explicitly ask for a break, and go does not.
So, this time stupid a back, hurriedly stick to the other code, find other Select-case branches, if you want to jump out for, are used return. Maybe the head went into the water when the code was written ...