Stopping a Goroutine with Signals
In Go, goroutines are lightweight threads that are used for concurrency. However, there may be scenarios where we need to terminate a goroutine prematurely. This article explores how to achieve this by using signaling mechanisms.
In the provided code, the goal is to stop a goroutine when a specific condition (tooLate) becomes true. However, using a second channel as proposed would indeed block the goroutine when read upon.
Using an Additional Channel with Select
A better approach involves creating a separate channel (tooLate) and using select in the goroutine to monitor both the processing channel (proCh) and the tooLate channel. When tooLate receives a signal, the goroutine can terminate gracefully.
<code class="go">package main import "fmt" import "time" func main() { tooLate := make(chan struct{}) proCh := make(chan string) go func() { for { fmt.Println("working") time.Sleep(1 * time.Second) select { case <-tooLate: fmt.Println("stopped") return case proCh <- "processed": default: // Adding default makes it non-blocking } fmt.Println("done here") } }() select { case proc := <-proCh: fmt.Println(proc) case <-time.After(1 * time.Second): fmt.Println("too late") close(tooLate) } time.Sleep(4 * time.Second) fmt.Println("finish\n") }</code>
In this updated code, when the timer expires (indicating it's too late), the tooLate channel is closed, sending a signal to the goroutine. The goroutine receives this signal and terminates accordingly.
Using sync.Cond
Another option to consider is using sync.Cond, which provides more granular control over signaling. However, it requires a bit more setup and synchronization logic.
The above is the detailed content of How to Gracefully Stop a Goroutine in Go Using Signals?. For more information, please follow other related articles on the PHP Chinese website!