How to Use context.WithCancel in Go: Simple Guide
In Go,
context.WithCancel creates a new context that can be canceled manually by calling the returned cancel function. This allows you to stop work in goroutines early and clean up resources when needed.Syntax
The context.WithCancel function returns two values: a new Context and a cancel function. You call the cancel function to signal cancellation to all goroutines using that context.
- ctx: The parent context, often
context.Background()orcontext.TODO(). - cancel: A function to call when you want to cancel the context.
go
ctx, cancel := context.WithCancel(parentCtx) // Use ctx in goroutines // Call cancel() to stop work
Example
This example shows how to start a goroutine that listens for cancellation using context.WithCancel. When cancel() is called, the goroutine stops its work and exits cleanly.
go
package main import ( "context" "fmt" "time" ) func worker(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("Worker: received cancellation signal, stopping.") return default: fmt.Println("Worker: working...") time.Sleep(500 * time.Millisecond) } } } func main() { ctx, cancel := context.WithCancel(context.Background()) go worker(ctx) // Let the worker run for 2 seconds time.Sleep(2 * time.Second) // Cancel the context to stop the worker cancel() // Wait a moment to see worker stop time.Sleep(1 * time.Second) }
Output
Worker: working...
Worker: working...
Worker: working...
Worker: working...
Worker: received cancellation signal, stopping.
Common Pitfalls
One common mistake is forgetting to call the cancel function, which can cause resource leaks because the context and its children remain active. Another is ignoring the ctx.Done() channel in goroutines, so they never stop when canceled.
Always call cancel() when the work is done or no longer needed, and check ctx.Done() in goroutines to handle cancellation properly.
go
/* Wrong: Not calling cancel() leads to resource leaks */ ctx, _ := context.WithCancel(context.Background()) // ... do work but never call cancel() /* Right: Call cancel() to release resources */ ctx, cancel := context.WithCancel(context.Background()) // ... do work cancel()
Quick Reference
- context.WithCancel(parentCtx): creates a cancelable context.
- cancel(): call to stop work and release resources.
- ctx.Done(): channel to listen for cancellation signal.
- Use in goroutines to stop work early.
- Always call
cancel()to avoid leaks.
Key Takeaways
Use context.WithCancel to create a context you can cancel manually.
Always call the cancel function to avoid resource leaks.
Check ctx.Done() in goroutines to stop work when canceled.
context.WithCancel helps manage goroutine lifecycles cleanly.
Use context.Background() as the parent context if none exists.