Ответ
Неблокирующие операции в Go — это операции с каналами, которые не заставляют горутину останавливаться и ждать. Если операция (отправка или получение) не может быть выполнена немедленно, горутина продолжает свою работу, а не блокируется.
Основной инструмент для этого — оператор select
в сочетании с default
.
1. Неблокирующее чтение из канала:
Попытаться прочитать данные из канала, но если данных нет — немедленно перейти к ветке default
.
messages := make(chan string)
// ... в другой горутине кто-то может отправить в канал
select {
case msg := <-messages:
fmt.Println("Получено сообщение:", msg)
default:
fmt.Println("Сообщений нет, идем дальше.")
}
2. Неблокирующая запись в канал:
Попытаться отправить данные в канал, но если буфер канала полон или получатель не готов — немедленно перейти к default
.
// Канал без буфера. Запись заблокируется, если нет читателя.
ch := make(chan int)
msg := 42
select {
case ch <- msg:
fmt.Println("Сообщение успешно отправлено")
default:
fmt.Println("Не удалось отправить сообщение, получатель не готов.")
}
Ключевые моменты:
select
сdefault
— это главный идиоматичный способ реализации неблокирующих операций с каналами.- Буферизированные каналы сами по себе не являются неблокирующими, но они могут предотвратить блокировку, пока буфер не заполнен (при записи) или не пуст (при чтении).
- Неблокирующие операции критически важны для предотвращения deadlock'ов и для написания высокоотзывчивых конкурентных программ.