How to Stop a goroutine in Golang
Created
Modified
A signal channel
Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
go func() {
for {
select {
case <-done:
fmt.Println("done")
return
default:
// ...
}
}
}()
fmt.Println("A")
time.Sleep(time.Millisecond)
done <- true
}
$ go run main.go A done
Using close Function
To close a channel, we call the built-in close function:
package main
import (
"fmt"
)
func main() {
c1 := make(chan int)
go func() {
for {
v, ok := <-c1
if !ok {
fmt.Println("done")
return
}
fmt.Println(v)
}
}()
c1 <- 1
c1 <- 2
close(c1)
// panic: send on closed channel
c1 <- 3
}
$ go run main.go 1 2 done panic: send on closed channel
Use the context
Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
package main
import (
"context"
"fmt"
)
func main() {
c1 := make(chan int)
ctx, cancel := context.WithCancel(context.Background())
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("done")
return
default:
fmt.Println(<-c1)
}
}
}(ctx)
c1 <- 1
c1 <- 2
cancel()
// fatal error:
c1 <- 3
}
$ go run main.go 1 2 done fatal error: all goroutines are asleep - deadlock!