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

Срок контекста в Go

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

Команда со сроком тоже возвращает функцию отмены. Ее нужно вызвать, когда контекст больше не нужен, даже если срок уже сработал: так освобождаются внутренние таймеры.

Зададим короткий срок и дождемся отмены в воркере:

package main import ( "context" "fmt" "time" ) func worker(ctx context.Context) { <-ctx.Done() fmt.Println("timeout") } func main() { ctx, cancel := context.WithTimeout( context.Background(), 50*time.Millisecond, ) defer cancel() go worker(ctx) <-ctx.Done() }

Программа печатает "timeout" и заканчивается без ручного вызова отмены в середине main: срок истек сам.

Срок можно комбинировать с ручной отменой: кто первый закроет Done, тот и остановит ветки. Ниже срок длиннее паузы, но отмену вызывают раньше:

package main import ( "context" "fmt" "time" ) func main() { ctx, cancel := context.WithTimeout( context.Background(), time.Second, ) defer cancel() go func() { <-ctx.Done() fmt.Println("end") }() time.Sleep(10 * time.Millisecond) cancel() <-ctx.Done() }

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

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

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

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

ctx, stop := context.WithTimeout( context.Background(), time.Millisecond, ) _ = ctx

Допишите отложенный вызов stop и скажите, зачем он нужен, если срок уже истек.

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

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