常规和关闭频道的异常行为

时间:2019-05-05 10:41:06

标签: go concurrency channel goroutine

根据Golang Documentation

  

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
        }
    }
}

可能是根本原因?我只是在这里大混乱。

0 个答案:

没有答案