Программы, процессы, потоки, горутины и планировщик G-M-P — простыми словами
Программа — это набор инструкций, написанных на языке программирования, которые говорят компьютеру, что делать. Это пассивный объект.
В компьютере это ваш скомпилированный файл (например, myapp.exe в Windows или myapp в Linux). Он лежит на диске и ждёт запуска.
Процесс — это экземпляр выполняющейся программы. Когда вы запускаете программу, ОС создаёт для неё процесс. Процесс — это активный объект.
Если в вашем процессе готовится борщ, это никак не влияет на соседний процесс, где пекут пирог. У каждого своя «кухня».
ОС выделяет каждому процессу свою память, файлы и другие ресурсы. Процессы не могут напрямую использовать память друг друга.
Поток — это наименьшая единица выполнения кода внутри процесса. Один процесс может иметь один или несколько потоков.
Если нанять помощника — на кухне появятся два потока. Один следит за супом, другой в это же время готовит салат. Они пользуются общими инструментами, что создаёт риск конфликтов — race condition.
Создать поток («нанять помощника») гораздо дешевле, чем создавать новый процесс («строить новую кухню»).
Все потоки внутри одного процесса имеют доступ к общей памяти. Это удобно для обмена данными, но создаёт риски.
Представьте, что вы — единственный работник на почте. Пока вы ждёте ответа сервера на запрос, вы ничего не делаете. Клиенты в очереди стоят и ждут. Программа «зависла».
Именно эту проблему решает конкурентность в Go — возможность переключаться на другие задачи, пока одна из них ожидает.
Deal with multiple things at once
Один бариста, но очень опытный. Ставит эспрессо вариться → переключается на американо → возвращается к капучино. В каждый момент он делает только одно, но умно жонглирует задачами.
Цель: отзывчивость программы. Работает и на одном ядре.
Do multiple things at once
Два бариста работают физически одновременно: один делает капучино, другой — американо. Задачи выполняются в одно и то же время.
Цель: скорость вычислений. Требует нескольких ядер CPU.
| Критерий | Конкурентность | Параллелизм |
|---|---|---|
| Суть | Структура кода | Способ выполнения на железе |
| Аналогия | 1 бариста, multitasking | 2 бариста одновременно |
| Железо | Достаточно 1 ядра | Нужно несколько ядер |
| Цель | Отзывчивость, правильная структура | Скорость, производительность |
Go не доверяет ОС управлять горутинами напрямую. Вместо этого у него есть собственный эффективный планировщик.
go myTask(). Планировщик кладёт горутину (G) в очередь P. Рабочий (M) берёт её и выполняет.GOMAXPROCS по умолчанию равен числу ядер — ничего настраивать не нужно.