A cancel function marks a context as done without stopping the program immediately.

cancel function `context.WithCancel` returns a child context and a function that records cancellation.

Cancel Signal

task
cancel_signal.go
Replay: real traced execution (multi-file project)
package main

import (
	"context"
	"fmt"
)

func main() {
	var task = "sync"
	ctx, cancel := context.WithCancel(context.Background())

	fmt.Println("task=", task)
	fmt.Println("beforeCancel=", ctx.Err() == nil)

	cancel()
	fmt.Println("afterCancel=", ctx.Err())
}
package main

import (
	"context"
	"fmt"
)

func main() {
	var task = "build"
	ctx, cancel := context.WithCancel(context.Background())

	fmt.Println("task=", task)
	fmt.Println("beforeCancel=", ctx.Err() == nil)

	cancel()
	fmt.Println("afterCancel=", ctx.Err())
}
package main

import (
	"context"
	"fmt"
)

func main() {
	var task = "review"
	ctx, cancel := context.WithCancel(context.Background())

	fmt.Println("task=", task)
	fmt.Println("beforeCancel=", ctx.Err() == nil)

	cancel()
	fmt.Println("afterCancel=", ctx.Err())
}
  1. task ← "sync", ctx ← &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}

    8func main() {9  var task→ "sync" = "sync" //@task="build", "review"10  ctx→ &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}, cancel→ (context.CancelFunc)(⟨addr A⟩) := context.WithCancel(context.Background())1112  fmt.Println("task=", task"sync")13  fmt.Println("beforeCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}.Err() == nil)1415  cancel()16  fmt.Println("afterCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:(chan struct {})(⟨addr B⟩)}, children:map[context.canceler]struct {}(nil), err:(*errors.errorString)(⟨addr C⟩), cause:(*errors.errorString)(⟨addr C⟩)}.Err())17}
    outputtask= sync
    beforeCancel= true
    afterCancel= context canceled
  1. task ← "build", ctx ← &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}

    8func main() {9  var task→ "build" = "build"10  ctx→ &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}, cancel→ (context.CancelFunc)(⟨addr A⟩) := context.WithCancel(context.Background())1112  fmt.Println("task=", task"build")13  fmt.Println("beforeCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}.Err() == nil)1415  cancel()16  fmt.Println("afterCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:(chan struct {})(⟨addr B⟩)}, children:map[context.canceler]struct {}(nil), err:(*errors.errorString)(⟨addr C⟩), cause:(*errors.errorString)(⟨addr C⟩)}.Err())17}
    outputtask= build
    beforeCancel= true
    afterCancel= context canceled
  1. task ← "review", ctx ← &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}

    8func main() {9  var task→ "review" = "review"10  ctx→ &context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}, cancel→ (context.CancelFunc)(⟨addr A⟩) := context.WithCancel(context.Background())1112  fmt.Println("task=", task"review")13  fmt.Println("beforeCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:interface {}(nil)}, children:map[context.canceler]struct {}(nil), err:error(nil), cause:error(nil)}.Err() == nil)1415  cancel()16  fmt.Println("afterCancel=", ctx&context.cancelCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, mu:sync.Mutex{state:0, sema:0x0}, done:atomic.Value{v:(chan struct {})(⟨addr B⟩)}, children:map[context.canceler]struct {}(nil), err:(*errors.errorString)(⟨addr C⟩), cause:(*errors.errorString)(⟨addr C⟩)}.Err())17}
    outputtask= review
    beforeCancel= true
    afterCancel= context canceled