В чем разница в работе тредов между сетевым вызовом и чтением файла

«В чем разница в работе тредов между сетевым вызовом и чтением файла» — вопрос из категории Linux, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сетевые вызовы в 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.