Короткий ответ
Процесс — независимая единица выполнения с собственным адресным пространством и своим интерпретатором Python. Поток — лёгкая единица внутри процесса: все потоки разделяют его память и данные.
Как это работает подробнее
Главные отличия лежат в модели памяти, стоимости создания и способности к параллельному исполнению.
- Память. Процессы изолированы и общаются через очереди, каналы и разделяемую память, а потоки напрямую читают и меняют общие объекты.
- Параллелизм. У каждого процесса свой GIL, поэтому они действительно выполняются на нескольких ядрах; потоки одного процесса для вычислений ограничены GIL.
- Стоимость. Процессы тяжелее: их создание и переключение дороже, а потоки создаются дёшево и быстро обмениваются данными.
- Синхронизация. Из-за общей памяти в потоках нужны блокировки против гонок данных, процессы в такой защите не нуждаются.
Что использовать на практике
- Процессы. Бери, когда нужны изоляция и настоящий параллелизм для вычислительных задач.
- Потоки. Бери для лёгких задач с интенсивным обменом данными при ожидании ввода-вывода.
- Обмен данными. Между процессами используй очереди multiprocessing или каналы вместо общей памяти.
Подводные камни
- Гонки данных. Без блокировок одновременное изменение общих объектов из разных потоков даёт непредсказуемые результаты.
- Тяжесть процессов. Запуск сотен процессов съедает много ресурсов по сравнению с потоками.
- Ограничение GIL. Не жди от потоков ускорения чистых вычислений в CPython.