Я в основном согласен с ответом Джиана, но у меня есть разные интерпретации нескольких примитивов параллелизма.Обратите внимание, что эти термины часто используются разными авторами непоследовательно.Это мои любимые определения (надеюсь, не слишком далеко от современного консенсуса).
- Процесс:
- Под управлением ОС
- Каждое имеет свое собственное виртуальное адресное пространство
- Может быть прервано (прервано) системой для запуска другого процесса
- Может работать параллельно с другими процессами на других процессорах
- Слишком высокая нагрузка на память процессов (включает таблицы виртуальной памяти, дескрипторы открытых файлов и т. д.)
- Затраты времени на создание и переключение контекста между процессами относительно высоки
- Потоки:
- Управляемый ОС
- Каждый из них "содержится" в каком-то конкретном процессе
- Все потоки в одном и том же процессе совместно используют одно и то же виртуальное адресное пространство
- Может быть прервано системой для разрешениядругой поток для запуска
- Может работать параллельно с другими потоками на разных процессорах
- Расходы памяти и времени, связанные с потоками, меньше, чемn процессов, но все еще нетривиальных
- (Например, обычно переключение контекста включает в себя вход в ядро и вызов системного планировщика.)
- Совместные потоки:
- Может или не может управляться ОС
- Каждый «содержится» в каком-то конкретном процессе
- В некоторых реализациях каждый «содержится» в каком-то конкретномПоток ОС
- Не может быть прерван системой, чтобы разрешить запуск кооперативного однорангового узла
- (Разумеется, содержащийся процесс / поток все еще может быть прерван)
- Должен вызывать специальный примитив yield, чтобы разрешить запуск потоков равноправных кооперативов
- Обычно нельзя запускать параллельно с кооперативными одноранговыми узлами
- Существует множество вариантов темы кооперативных нитей, которые называются разными именами:
- Волокна
- Зеленые нити
- Протопотоки
- Потоки пользовательского уровня (потоки пользовательского уровня могут быть прерывистыми / вытесняющими, но это довольно необычная комбинация)
- В некоторых реализациях кооперативных потоков используются такие методы, как стеки разделения / сегментирования илидаже индивидуальное выделение кучи для каждого кадра вызова, чтобы уменьшить накладные расходы памяти, связанные с предварительным выделением большого куска памяти для стека
- В зависимости от реализации, вызов системного вызова блокировки (например, чтение из сети или спящий режим)либо блокирует целую группу взаимодействующих потоков, либо неявно приводит к тому, что вызывающий поток выдает
- Сопрограммы:
- Некоторые люди используют "сопрограмму" и "кооперативный поток"более или менее синонимично
- Я не предпочитаю это использование
- Некоторые реализации сопрограмм на самом деле являются "мелкими" кооперативными потоками;yield может быть вызван только «процедурой ввода сопрограммы»
- Легкая (или полу-сопрограммная) версия проще в реализации, чем потоки, поскольку для каждой сопрограммы не требуется полный стек (только один кадр для записипроцедура)
- Часто в сопрограммных каркасах есть примитивы выхода, которые требуют от вызывающего явно указывать, какой контроль сопрограмм следует передать
- Генераторам:
- Restricted (мелкий) сопрограммы
- yield может возвращать управление только тому коду, который вызвал генератор
- Запрограммировано:
- Странный гибрид кооперативных потоков и потоков ОС
- Невозможно прервать (как взаимодействующие потоки)
- Может работать параллельно в управляемом языком пуле потоков ОС
- Обработчики событий:
- Процедуры / методы, которые вызываются диспетчером событий в ответ на какое-либо происходящее действие
- Очень популярны для программирования пользовательского интерфейса
- Немного не требуют поддержки языка / системы;может быть реализован в библиотеке
- Одновременно может работать не более одного обработчика событий;диспетчер должен дождаться окончания обработки (возврата) обработчика перед началом следующего
- Делает синхронизацию относительно простой;различные исполнения обработчиков никогда не перекрываются во времени
- Реализация сложных задач с обработчиками событий приводит к «инвертированному потоку управления» / «копированию стека»
- Задачи:
- Единицы работы, которые распределяются менеджером в пул работников
- Работниками могут быть потоки, процессы или машины
- Конечно, видРаботник, используемый библиотекой задач, оказывает значительное влияние на то, как реализуются задачи.
- В этом списке непоследовательной и запутанной терминологии «задача» берет корону.В частности, в сообществе встраиваемых систем «задача» иногда используется для обозначения «процесс», «поток» или «обработчик события» (обычно называемый «подпрограммой обработки прерывания»).Это также иногда используется в общем / неформальном виде для обозначения любого вида единиц вычислений.
Одна любимая мозоль, которую я не могу удержать от проветривания: мне не нравится использованиефразы «истинный параллелизм» для «процессорного параллелизма».Это довольно часто, но я думаю, что это приводит к большой путанице.
Для большинства приложений я думаю, что основанные на задачах платформы лучше всего подходят для распараллеливания.Большинство популярных (Intel TBB, Apple GCD, Microsoft TPL & PPL) используют потоки в качестве рабочих.Хотелось бы, чтобы было несколько хороших альтернатив, использующих процессы, но я не знаю ни о каких.
Если вы заинтересованы в параллелизме (в отличие от параллелизма процессора), обработчики событий - самый безопасный путь.Кооперативные темы - интересная альтернатива, но немного дикого запада.Пожалуйста, не используйте потоки для параллелизма, если вы заботитесь о надежности и надежности вашего программного обеспечения.