According to Golang Documentation,
A
defer
statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns. Defer is commonly used to simplify functions that perform various clean-up actions.
In other words, go defer
temporarily holds the execution of command until the surrounding function returns. I wrote a simple go program which contains several goroutines, which should terminate 8 reader
goroutines upon the termination of the looper
goroutine.
func main(){
// declaring handler
handler := make(chan int)
var wg sync.WaitGroup
// execute reader as 8 separate processes
for i := 0; i < 8; i++ {
go reader(handler, &wg)
}
// timer which fires an event once in a second
ticker := time.NewTicker(1 * time.Second)
// the channel which carries out termination signal
terminator := make(chan interface{})
go looper(ticker.C, handler, terminator)
// wait for 5 Seconds
time.Sleep(time.Second * 5)
// terminate looper
close(terminator)
//wait for reader functions to do their work
wg.Wait()
}
// receive val from looper and process it
func reader(handler <-chan int, wg *sync.WaitGroup) {
wg.Add(1)
defer wg.Done()
for val := range handler {
fmt.Printf("Received %d
", val)
time.Sleep(2 * time.Second) //just to simulate a lengthy process
}
}
in the program, if I close the handler channel using defer
, it works fine.
func looper(ticker <-chan time.Time, handler chan<- int, terminator <-chan interface{}) {
arr := []int{1, 2, 3, 4, 5}
defer close(handler)
for {
select {
case <-ticker:
for _, val := range arr {
// passed the index to communication channel
handler <- val
}
case <-terminator:
return
}
}
}
But if I close the handler channel just before the return statement as follows, the program exists without printing anything
func looper(ticker <-chan time.Time, handler chan<- int, terminator <-chan interface{}) {
arr := []int{1, 2, 3, 4, 5}
for {
select {
case <-ticker:
for _, val := range arr {
// passed the val to reader
handler <- val
}
case <-terminator:
close(handler)
return
}
}
}
What could be the root cause? I'm just having a BIG confusion there.