Ответ
Сетевые вызовы в Go блокируют горутину, но не поток (M) из пула. Когда горутина блокируется на сетевом вызове, рантайм переключает её на другую горутину в том же потоке. Это возможно благодаря асинхронному вводу-выводу через системные вызовы (epoll/kqueue).
Чтение файлов обычно блокирует и горутину, и поток, если не используется syscall.O_NONBLOCK или асинхронный API. В Linux можно использовать io_uring для асинхронного чтения файлов.
Пример с сетевым вызовом:
resp, err := http.Get("https://example.com") // Блокирует горутину, но не поток
Пример с файлом (блокирует поток):
data, err := os.ReadFile("file.txt") // Блокирует и горутину, и поток
Для неблокирующего чтения файлов можно использовать пакет aio или io_uring.