Функция context.WithCancel
Функция context.WithCancel создает новый контекст,
который является производным от переданного родительского контекста.
Она возвращает два значения: новый контекст и функцию отмены.
Первый параметр — родительский контекст, от которого
будет создан дочерний контекст.
Синтаксис
ctx, cancel := context.WithCancel(parent)
Базовый пример
Давайте создадим контекст с отменой и используем его для завершения горутины по сигналу:
package 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)
}
Результат выполнения кода:
"work cancelled"
Пример с проверкой ошибки отмены
Проверим, какую ошибку возвращает контекст после вызова функции отмены:
package main
import (
"context"
"fmt"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
cancel()
err := ctx.Err()
fmt.Println(err)
}
Результат выполнения кода:
"context canceled"
Пример с несколькими горутинами
Продемонстрируем, как одна функция отмены останавливает несколько горутин:
package 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)
}
Результат выполнения кода:
"worker 3 stopped"
"worker 2 stopped"
"worker 1 stopped"
Смотрите также
-
функцию
context.WithCancelCause,
которая позволяет задать причину отмены -
функцию
context.WithTimeout,
которая отменяет контекст по истечении времени -
тип
context.CancelFunc,
который представляет функцию отмены -
функцию
context.Cause,
которая возвращает причину отмены контекста