Функция context.WithCancel

Функция context.WithCancel создает новый контекст, который является производным от переданного родительского контекста. Она возвращает два значения: новый контекст и функцию отмены. Первый параметр — родительский контекст, от которого будет создан дочерний контекст.

Синтаксис

goctx, cancel := context.WithCancel(parent)

Базовый пример

Давайте создадим контекст с отменой и используем его для завершения горутины по сигналу:

gopackage main

import (
  "context"
  "fmt"
  "time"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  defer cancel()

  go func() {
    select {
    case <-time.After(2 * time.Second):
      fmt.Println("work done")
    case <-ctx.Done():
      fmt.Println("work cancelled")
    }
  }()

  time.Sleep(1 * time.Second)
  cancel()
  time.Sleep(100 * time.Millisecond)
}

Результат выполнения кода:

go"work cancelled"

Пример с проверкой ошибки отмены

Проверим, какую ошибку возвращает контекст после вызова функции отмены:

gopackage main

import (
  "context"
  "fmt"
)

func main() {
  ctx, cancel := context.WithCancel(context.Background())
  cancel()

  err := ctx.Err()
  fmt.Println(err)
}

Результат выполнения кода:

go"context canceled"

Пример с несколькими горутинами

Продемонстрируем, как одна функция отмены останавливает несколько горутин:

gopackage main

import (
  "context"
  "fmt"
  "time"
)

func worker(ctx context.Context, id int) {
  select {
  case <-ctx.Done():
    fmt.Printf("worker %d stopped\n", id)
    return
  }
}

func main() {
  ctx, cancel := context.WithCancel(context.Background())

  for i := 1; i <= 3; i++ {
    go worker(ctx, i)
  }

  time.Sleep(50 * time.Millisecond)
  cancel()
  time.Sleep(100 * time.Millisecond)
}

Результат выполнения кода:

go"worker 3 stopped"
"worker 2 stopped"
"worker 1 stopped"

Смотрите также

  • функцию context.WithCancelCause,
    которая позволяет задать причину отмены
  • функцию context.WithTimeout,
    которая отменяет контекст по истечении времени
  • тип context.CancelFunc,
    который представляет функцию отмены
  • функцию context.Cause,
    которая возвращает причину отмены контекста