Ответ
Network Poller (сетевой опросчик) в Go — это низкоуровневый механизм рантайма, который является ключевой частью неблокирующей модели ввода-вывода (I/O) в Go.
Его главная задача — эффективно обрабатывать сетевые операции, не блокируя системные потоки (OS threads), что позволяет достигать высокой конкурентности при минимальных затратах ресурсов.
Принцип работы:
- Инициация операции: Горутина выполняет блокирующую сетевую операцию (например,
net.Conn.Read()
). - Перехват рантаймом: Рантайм Go перехватывает этот вызов. Вместо того чтобы заблокировать весь системный поток, он регистрирует файловый дескриптор сокета в Network Poller (используя системные вызовы, такие как
epoll
в Linux,kqueue
в macOS/BSD илиIOCP
в Windows). - Парковка горутины: Горутина, инициировавшая операцию, переводится в состояние ожидания, а планировщик Go запускает на этом же системном потоке другую готовую к выполнению горутину.
- Ожидание события: Network Poller асинхронно ожидает сигнала от операционной системы о том, что по сокету можно читать или писать данные.
- Возобновление горутины: Как только событие наступает, Network Poller уведомляет планировщик, который перемещает ожидавшую горутину обратно в очередь готовых к выполнению.
Пример кода:
conn, _ := net.Dial("tcp", "example.com:80")
buf := make([]byte, 1024)
// Для разработчика вызов выглядит блокирующим,
// но под капотом рантайм паркует горутину и освобождает поток.
n, _ := conn.Read(buf)
fmt.Println(string(buf[:n]))
Ключевые преимущества:
- Масштабируемость: Позволяет обслуживать тысячи сетевых соединений с помощью небольшого количества системных потоков.
- Эффективность: Системные потоки не простаивают в ожидании I/O, а постоянно выполняют полезную работу.
- Простота для разработчика: Сложность асинхронного I/O скрыта внутри рантайма, а код остается простым и последовательным.