Search code examples
gochannelticker

what's wrong with the golang code by using ticker


package main

import (
    "fmt"
    "time"
)

func main() {
    intChan := make(chan int, 1)
    ticker := time.NewTicker(time.Second)
    go func() {
        for _ = range ticker.C {
            select {
            case intChan <- 1:
            case intChan <- 2:
            case intChan <- 3:
            }
        }
        /*defer */
        fmt.Println("End. [sender]")
    }()
    var sum int
    for e := range intChan {
        fmt.Printf("Received: %v\n", e)
        sum += e
        if sum > 10 {
            fmt.Printf("Got: %v\n", sum)
            break
            //ticker.Stop()
        }
    }
    fmt.Println("End. [receiver]")
    //time.Sleep(10)
}

I'm new in golang. In this code, I want print "End. [sender]" once when the goroutine is over. I try to use ticker.stop(), or even time.sleep(), defer , but no effect. What's wrong with it, please give me some idea. thanks


Solution

  • As documentation says, ticker.Stop doesn't close channel. So you must not expect break-loop. You can add new channel for quit.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        intChan := make(chan int, 2)
        ticker := time.NewTicker(time.Second)
        quit := make(chan bool)
        go func() {
        loop:
            for {
                select {
                case <-ticker.C:
                    select {
                    case intChan <- 1:
                    case intChan <- 2:
                    case intChan <- 3:
                    }
                case <-quit:
                    break loop
                }
            }
            /*defer */
            fmt.Println("End. [sender]")
            close(intChan)
        }()
        var sum int
        for e := range intChan {
            fmt.Printf("Received: %v\n", e)
            sum += e
            if sum > 10 {
                fmt.Printf("Got: %v\n", sum)
                quit <- true
                //break
                //ticker.Stop()
            }
        }
        fmt.Println("End. [receiver]")
        //time.Sleep(10)
    }