IMO наибольшее внимание вокруг каждого - профиль масштабирования. Масштабирование потоков и многопроцессорности зависит от количества потоков / процессов, доступных для вашей программы, в то время как асинхронное масштабирование может линейно масштабироваться для рабочих нагрузок на основе ввода-вывода в зависимости от количества доступных процессов.
Многопоточный
Из-за GIL я не видел, чтобы темы использовались очень часто. Uwsgi, сельдерей и другие структуры предлагают потокового работника. Вот некоторые из положительных сторон потоков:
- собственная поддержка
- Если вы знаете, что ваша рабочая нагрузка связана с вводом-выводом, использовать модель потоков с меньшей степенью сложности, чтобы разделить единое адресное пространство, может быть менее сложно.
- Пропускная способность масштабируется с учетом количества доступных процессов
Причины, по которым я НЕ рекомендовал бы потоки:
- Условия гонки / безопасность потоков
Многие приложения (сторонние модули) не учитывают это и могут иметь общую память и открывать приложение для условий гонки. Это то, на что нужно обратить внимание, и я вижу это часто.
Мультипроцесс
Uwsgi / Celery :) В моем опыте это примитив параллелизма по умолчанию, потому что параллелизм возможен, меньше шансов на условия гонки, поддержка стандартной библиотеки и не GIL.
Плюсы:
- Стандартные библиотечные примитивы
Минусы:
- Управление процессами (т.е. необходимо следить за работоспособностью процессов)
- Масштаб пропускной способности в зависимости от количества доступных процессов
Asyncio
Twisted, tornado и asyncio.
Это очень часто встречается в веб-или сетевых инфраструктурах, потому что большая часть их работы обычно основывается на IO-нагрузках. Асинхронный ввод-вывод позволяет одному потоку одновременно обрабатывать сотни, тысячи, десятки тысяч или даже миллион :) соединений. Сравните это с моделью, основанной на предварительной ветке или на основе процесса, для которой требуется одновременный запрос процесса.
Основным недостатком этого является то, что поскольку инфраструктуры асинхронного ввода-вывода обычно являются однопоточными, любые связанные с ЦП рабочие нагрузки будутблокировать продвижение вперед цикла обработки событий, что является очень распространенной операционной проблемой для сред выполнения, таких как node / v8.