Контекст и отмена
Условие задачи
Реализуй воркер, который каждую секунду выводит сообщение: "Working...". Через 3 секунды основной поток должен отменить контекст, и воркер должен завершиться корректно.
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
// TODO: работай до отмены
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx)
// TODO: через 3 секунды вызвать cancel()
}
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
// TODO: работай до отмены
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx)
// TODO: через 3 секунды вызвать cancel()
}
Подсказка
- Используй <-ctx.Done() внутри воркера, чтобы узнать, когда контекст отменён. - Не забудь вызвать cancel() — это важно для освобождения ресурсов.
Решение
Контекст позволяет удобно передавать сигнал отмены между потоками. Это особенно важно для graceful shutdown.
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Работа остановлена")
return
default:
fmt.Println("Working...")
time.Sleep(time.Second)
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx)
time.Sleep(3 * time.Second)
cancel()
time.Sleep(time.Second)
}
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Работа остановлена")
return
default:
fmt.Println("Working...")
time.Sleep(time.Second)
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx)
time.Sleep(3 * time.Second)
cancel()
time.Sleep(time.Second)
}