Вопрос проверяет понимание механизмов отмены и таймаутов в Go через пакет context, что необходимо для управления горутинами и предотвращения утечек ресурсов.
В Go пакет context предоставляет стандартный способ передачи сигналов отмены и дедлайнов между горутинами. context.WithCancel создает дочерний контекст с функцией cancel, которую можно вызвать для отмены всех операций, использующих этот контекст. context.WithTimeout делает то же самое, но автоматически вызывает отмену по истечении заданного времени.
Когда вы создаете контекст с помощью context.WithCancel, вы получаете новый контекст и функцию отмены. Вызов этой функции отправляет сигнал всем горутинам, которые слушают канал Done() этого контекста. context.WithTimeout внутри использует context.WithDeadline, устанавливая абсолютное время завершения.
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Worker stopped:", ctx.Err())
return
default:
fmt.Println("Working...")
time.Sleep(500 * time.Millisecond)
}
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
go worker(ctx)
time.Sleep(3 * time.Second)
fmt.Println("Main done")
}Итог: Используйте context.WithCancel для явного управления жизненным циклом горутин, а context.WithTimeout — для автоматического прерывания операций, превышающих допустимое время. Это ключевые инструменты для написания надежных и отзывчивых Go-приложений.