defer
语句将函数调用推送到列表上。周围函数返回后,将执行保存的呼叫列表。 Defer通常用于简化执行各种清理操作的功能。
换句话说,转到defer
暂时保留命令的执行,直到周围的函数返回为止。
我编写了一个简单的go程序,其中包含几个goroutine,它们应在reader
goroutine终止后终止8个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\n", val)
time.Sleep(2 * time.Second) //just to simulate a lengthy process
}
}
在程序中,如果我使用defer
关闭处理程序通道,则可以正常工作。
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
}
}
}
但是,如果我按如下所示在return语句之前关闭处理程序通道,则该程序存在而不打印任何内容
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
}
}
}
可能是根本原因?我只是在这里大混乱。