Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpCtCn 175 of 280 menu
◀ ▶

Отмена контекста в Go

От родительского контекста можно получить дочерний и функцию отмены. Пока отмену не вызвали, дочерний ведет себя как родитель; после вызова закрывается канал Done, и все, кто ждал этот сигнал, могут завершить работу.

Функцию отмены обычно вызывают через отложенный вызов, чтобы сигнал ушел и при обычном выходе, и при раннем возврате из функции.

Воркер ждет отмену и печатает знак остановки; в main отмену вызывают сразу после запуска ветки:

package main import ( "context" "fmt" ) func worker(ctx context.Context) { <-ctx.Done() fmt.Println("stopped") } func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() go worker(ctx) cancel() }

На экране "stopped". Закрытие канала Done разблокировало ожидание в worker.

Тот же прием в цикле: на каждой итерации проверяют, не отменили ли контекст:

package main import ( "context" "fmt" ) func tick(ctx context.Context) { for i := 0; i < 5; i++ { select { case <-ctx.Done(): fmt.Println("break at", i) return default: fmt.Println("step", i) } } } func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() go tick(ctx) cancel() }

Дан следующий код:

parent := context.Background() go func(ctx context.Context) { <-ctx.Done() fmt.Println("halt") }(parent)

От parent получите контекст с ручной отменой, передайте его в ветку, объявите функцию отмены с отложенным вызовом и вызовите ее из main.

Дан следующий код:

ctx, stop := context.WithCancel(context.Background()) _ = ctx

Скажите, что произойдет с каналом Done у ctx, если stop ни разу не вызвать до конца программы.

Скажите, зачем функцию отмены часто вешают на defer сразу после получения пары контекст и отмена.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить