Каковы основные преимущества использования модели параллелизма, основанной на процессах, по сравнению с моделью, основанной на потоках, и в каких контекстах последняя подходит?
Параллелизм: процессы против потоков
Ответы (4)
Отказоустойчивость и масштабируемость - основные преимущества использования процессов по сравнению с потоками.
Система, основанная на разделяемой памяти или какой-либо другой технологии, доступной только при использовании потоков, будет бесполезна, если вы захотите запустить систему на нескольких машинах. Рано или поздно вам понадобится общаться между разными процессами.
При использовании процессов вы вынуждены иметь дело с коммуникацией через сообщения, например, именно так Erlang обрабатывает коммуникацию. Данные не передаются, поэтому нет риска повреждения данных.
Еще одно преимущество процессов заключается в том, что они могут давать сбой, и вы можете чувствовать себя в относительной безопасности, зная, что вы можете просто перезапустить их (даже на сетевых узлах). Однако, если поток дает сбой, это может привести к сбою всего процесса, что может привести к остановке всего вашего приложения. Чтобы проиллюстрировать: если процесс Erlang выйдет из строя, вы потеряете только этот телефонный звонок или этот веб-запрос и т. Д. Не все приложение.
Говоря все это, процессы ОС также имеют много недостатков, которые могут затруднить их использование, например, тот факт, что для создания нового процесса требуется вечность. Однако в Erlang есть свое собственное представление о процессах, которые чрезвычайно легки.
С учетом сказанного, это обсуждение действительно является предметом исследования. Если вы хотите получить более подробную информацию, вы можете дать статью Джо Армстронга об отказоустойчивых системах] 1 прочтение, оно многое объясняет об Erlang и философии, которая им движет.
Недостаток использования модели, основанной на процессах, заключается в том, что она работает медленнее. Вам придется копировать данные между параллельными частями вашей программы.
Недостатком использования потоковой модели является то, что вы, вероятно, ошибетесь. Это может показаться грубым, но это правда - покажите мне код, основанный на потоках, и я покажу вам ошибку. Я обнаружил ошибки в многопоточном коде, который работал «правильно» в течение 10 лет.
Преимущества использования модели, основанной на процессах, многочисленны. Разделение заставляет вас думать в терминах протоколов и формальных схем общения, а это означает, что гораздо более вероятно, что вы все сделаете правильно. Процессы, взаимодействующие друг с другом, легче масштабировать на нескольких машинах. Множественные параллельные процессы позволяют одному процессу аварийно завершить работу, не обязательно вызывая сбой других.
Преимущество использования потоковой модели в том, что она быстра.
Может быть очевидно, какой из двух я предпочитаю, но если это не так: процессы, каждый день недели и дважды в воскресенье. Потоки слишком сложны: я никогда не встречал никого, кто мог бы написать правильный многопоточный код; те, кто утверждает, что могут, как правило, еще недостаточно разбираются в космосе.
В этом случае процессы более независимы друг от друга, в то время как потоки разделяют некоторые ресурсы, например объем памяти. Но в общем случае потоки более легкие, чем процессы.
Процессы Erlang - это не то же самое, что процессы ОС. Процессы Erlang очень легкие, и Erlang может иметь много процессов Erlang в одном потоке ОС. См. Технически, почему процессы в Erlang более эффективны, чем Обсуждения ОС?
Прежде всего, процессы отличаются от потоков главным образом тем, как обрабатывается их память:
Process = n*Thread + memory region (n>=1)
Процессы имеют свою изолированную память. Процессы могут иметь несколько потоков.
Процессы изолированы друг от друга на уровне операционной системы. В процессе потоки делятся своей памятью со своими сверстниками. (Это часто нежелательно. Существуют библиотеки и методы, чтобы исправить это, но обычно это искусственный слой поверх потоков операционной системы.)
Память - это самый важный различающий фактор, так как он имеет определенные последствия:
- Обмен данными между процессами происходит медленнее, чем между потоками. Нарушение изоляции процесса всегда требует участия вызовов ядра и переназначения памяти.
- Потоки более легкие, чем процессы. Операционная система должна выделять ресурсы и управлять памятью для каждого процесса.
- Использование процессов обеспечивает изоляцию и синхронизацию памяти. Общие проблемы с доступом к памяти, разделяемой между потоками, вас не беспокоят. Поскольку вам нужно приложить особые усилия для обмена данными между процессами, вы, скорее всего, автоматически синхронизируете с этим.
Использование процессов дает вам хорошую (или окончательную) инкапсуляцию. Поскольку межпроцессное взаимодействие требует особых усилий, вам придется определить чистый интерфейс. Хорошая идея - отделить определенные части вашего приложения от основного исполняемого файла. Может быть, вы сможете таким образом разделить зависимости. например Process_RobotAi <-> Process_RobotControl
ИИ будет иметь совершенно разные зависимости по сравнению с управляющим компонентом. Интерфейс может быть простым: Process_RobotAI --DriveXY--> Process_RobotControl
. Может быть, вы поменяете платформу робота. Вам нужно только реализовать новый RobotControl
исполняемый файл с этим простым интерфейсом. Вам не нужно ничего трогать или даже перекомпилировать в компоненте AI.
Кроме того, по тем же причинам в большинстве случаев это ускоряет компиляцию.
Изменить: для полноты картины я беззастенчиво добавлю то, о чем мне напомнили другие: процесс сбоя (не обязательно) приводит к сбою всего вашего приложения.
В целом:
- Хотите создать что-то очень параллельное или синхронное, например алгоритм с n >> 1 экземплярами, работающими параллельно и обменивающимися данными, используйте потоки.
- Иметь систему с несколькими компонентами, которым не нужно обмениваться данными или алгоритмами, и они не обмениваются данными слишком часто, используйте процессы. Если вы используете библиотеку RPC для межпроцессного взаимодействия, вы получаете решение, распространяемое по сети, без каких-либо дополнительных затрат.
1 и 2 - крайние и простые сценарии, все между ними должно решаться индивидуально.
Хороший (или потрясающий) пример системы, интенсивно использующей IPC / RPC, можно найти на странице ros.