Сравните накладные расходы на системные вызовы (syscall) в модели с процессами (например, PostgreSQL) и в модели с горутинами (Go).

Ответ

Системный вызов (syscall) сам по себе — это обращение к ядру ОС, и его стоимость не зависит от того, кто его вызвал. Однако накладные расходы, связанные с блокировкой при системном вызове, кардинально различаются.

В этом сравнении модель с горутинами значительно эффективнее.

Модель с горутинами в Go

  1. Планировщик M:N: Go использует собственный планировщик, который отображает M горутин на N потоков ОС. Горутины — это легковесные потоки, управляемые рантаймом Go, а не ядром ОС.
  2. Неблокирующие syscalls: Когда горутина выполняет блокирующий системный вызов (например, чтение из сети), рантайм Go может "увидеть" это. Он открепляет текущий поток ОС (N) от этой горутины и передает его другой готовой к выполнению горутине (M).
  3. Результат: Переключение контекста происходит между горутинами в рамках одного процесса, что чрезвычайно дёшево. Поток ОС не блокируется и продолжает выполнять полезную работу. Это позволяет эффективно обслуживать тысячи одновременных соединений с небольшим количеством потоков ОС.

Модель с процессами в PostgreSQL (классическая)

  1. Процесс на соединение: PostgreSQL по умолчанию создает отдельный процесс ОС для каждого клиентского соединения. Каждый процесс имеет собственное адресное пространство и управляется напрямую ядром ОС.
  2. Блокирующие syscalls: Когда процесс выполняет блокирующий системный вызов, ядро ОС переводит весь процесс в состояние ожидания.
  3. Результат: Чтобы система продолжила выполнять другую работу, ядро должно выполнить полноценное переключение контекста на другой процесс. Это дорогостоящая операция, включающая смену адресного пространства, таблиц страниц памяти и т.д. Из-за этого масштабирование на десятки тысяч одновременных соединений становится проблематичным и ресурсоемким.

Итог

ХарактеристикаGo (горутины)PostgreSQL (процессы)
Единица конкурентностиГорутина (легковесная)Процесс (тяжеловесный)
Переключение контекстаДешевое (внутри процесса)Дорогое (между процессами)
Реакция на блокировкуПоток ОС выполняет другую горутинуВесь процесс блокируется
МасштабируемостьОчень высокаяОграниченная

Таким образом, накладные расходы, связанные с конкурентной обработкой блокирующих системных вызов, в Go на порядки ниже, чем в традиционной модели "процесс на соединение".