Search code examples
gogoroutine

how to stop a goroutine which may or may not be running?


I have a go func which I want to stop if running its running in default. The below approach get's blocked at quit <- true if go func already returned.

quit := make(chan bool)
go func() {
    for {
        select {
        case <- quit:
            return
        default:
            // Do other stuff and return if complete.
        }
    }
}()

// Do stuff

// Quit goroutine
quit <- true

Solution

  • Close the quit channel instead of sending a value. The loop will exit because receive on a closed channel returns a zero value.

    Also, declare the channel as chan struct{} to indicate that the channel values are unimportant to the program:

    quit := make(chan struct{})
    go func() {
        for {
            select {
            case <- quit:
                return
            default:
                // Do other stuff and return if complete.
            }
        }
    }()
    
    // Do stuff
    
    // Quit goroutine
    close(quit)
    

    If you need to break out of "other stuff", then pass the quit channel to the "other stuff" and check every now and again with:

    select {
    case <- quit:
        return
    default:
    }
    ... keep going
    

    If you are doing anything more than the first snippet in this answer, then you should consider using the standard context package for cancelation signals.