Подтвердить что ты не робот

Процессы, потоки, зеленые нити, прототипы, волокна, сопрограммы: какая разница?

Я читаю concurrency. Я немного переусердствовал с терминами, которые имеют смутно сходные определения. А именно:

  • Процессы
  • Темы
  • "Зеленые потоки"
  • Protothreads
  • Волокна
  • Сопрограммы
  • "Goroutines" на языке Go.

Мое впечатление состоит в том, что различия основываются на (1) действительно ли параллельном или мультиплексированном; (2) независимо от того, управляется ли он в CPU, в ОС или в программе; и (3..5) несколько других вещей, которые я не могу идентифицировать.

Есть ли краткий и недвусмысленный справочник по различиям между этими подходами к parallelism?

4b9b3361

Ответ 1

Хорошо, я сделаю все возможное. Во всем мире есть оговорки, но я сделаю все возможное, чтобы дать понять эти термины и ссылки на то, что приближается к определению, которое я дал.

  • Process: OS-управляемая (возможно) действительно параллельная, по крайней мере, при наличии подходящей аппаратной поддержки. Существуют внутри их собственного адресного пространства.
  • Thread: управляется ОС, в том же адресном пространстве, что и родительский и все остальные его потоки. Возможно, действительно одновременный, и многозадачность является упреждающей.
  • Green Thread: Это проекции пространства пользователя той же концепции, что и потоки, но не управляются ОС. Вероятно, это не совсем одновременное, за исключением того, что может быть несколько рабочих потоков или процессов, дающих им процессорное время одновременно, поэтому, вероятно, лучше всего рассматривать это как чередующиеся или мультиплексированные.
  • Protothreads: Я не мог дразнить определение из них. Я думаю, что они чередуются и управляются программой, но не верьте мне на слово. Я имел в виду, что они по сути являются реализацией приложения той же модели "зеленых потоков" с соответствующей модификацией для домена приложения.
  • Волокно: OS-управляется. Точно потоки, за исключением кооперативной многозадачности и, следовательно, не по-настоящему одновременной.
  • Coroutines: точно волокна, за исключением OS-управляемых.
  • Goroutines: они утверждают, что они не похожи ни на что другое, но они кажутся ровно зелеными нитями, как в, управляются процессом в одно адресное пространство и мультиплексирование на потоки системы. Возможно, кто-то, у кого больше знаний о Go, может пропустить маркетинговый материал.

Также стоит отметить, что в теории concurrency есть понятие понимания термина "процесс", в смысле calculation. Это определение ортогонально вышеприведенному, но я просто подумал, что стоит упомянуть, чтобы не возникало путаницы, если бы вы видели, что процесс использовался в этом смысле где-то.

Также обратите внимание на разницу между parallel и параллельным. Возможно, вы использовали первое в своем вопросе, где, я думаю, вы имели в виду последний.

Ответ 2

Я в основном согласен с ответом Джиана, но у меня разные интерпретации нескольких примитивов concurrency. Обратите внимание, что эти термины часто используются непоследовательно разными авторами. Это мои любимые определения (надеюсь, не слишком далеко от современного консенсуса).

  • Процесс:
    • OS управляемого
    • У каждого есть свое виртуальное адресное пространство
    • Может быть прервано (выгружено) системой, чтобы разрешить запуск другого процесса
    • Может работать параллельно с другими процессами на разных процессорах.
    • Накладные расходы на память процессов высоки (включая таблицы виртуальной памяти, открытые дескрипторы файлов и т.д.)
    • Временные накладные расходы для создания и переключения контекста между процессами относительно высоки.
  • Темы:
    • OS управляемого
    • Каждый из них "содержится" в определенном процессе
    • Все потоки в одном процессе имеют одно и то же виртуальное адресное пространство.
    • Может быть прервана системой, чтобы разрешить запуск другого потока
    • Может работать параллельно с другими потоками на разных процессорах.
    • Накладные расходы памяти и времени, связанные с потоками, меньше процессов, но все же нетривиальные
      • (Например, обычно переключение контекста включает ввод ядра и вызов системного планировщика.)
  • Совлокальные темы:
    • Может или не может управляться ОС.
    • Каждый из них "содержится" в определенном процессе
    • В некоторых реализациях каждый из них "содержится" в каком-то конкретном потоке ОС
    • Не может быть прервана системой, чтобы позволить совместному сверстнику
      • (Конечно, содержащий процесс/поток может быть прерван)
    • Должен вызывать специальный примитив yield, позволяющий запускать потоки одноранговых кооперативов
    • Как правило, нельзя запускать параллельно с совместными сверстниками
    • В теме кооперативной темы есть много вариаций, которые используются разными именами:
      • Волокна
      • Зеленые темы
      • Protothreads
      • Потоки пользовательского уровня (потоки пользовательского уровня могут быть прерывистыми/превентивными, но это относительно необычная комбинация)
    • В некоторых реализациях совлокальных потоков используются такие методы, как разделенные/сегментированные стеки или даже индивидуальное распределение кучи каждого кадра вызова, чтобы уменьшить служебные данные памяти, связанные с предварительным распределением большого фрагмента памяти для стека.
    • В зависимости от реализации вызов сценария блокировки (например, чтение из сети или спящего) приведет к тому, что целая группа кооперативных потоков блокирует или неявно приводит к тому, что вызывающий поток будет
  • Сопрограммы:
    • Некоторые люди используют "сопрограмму" и "кооперативную нить" более или менее синонимично
      • Я не предпочитаю это использование
    • Некоторые реализации coroutine на самом деле являются "неглубокими" кооперативными потоками; выход может быть вызван только процедурой ввода coroutine
    • Неглубокая (или полукорутинная) версия проще реализовать, чем потоки, поскольку каждая сопрограмма не нуждается в полном стеке (всего один кадр для процедуры ввода)
    • Часто структуры coroutine имеют примитивы доходности, которые требуют, чтобы invoker явно указывал, что управление сопрограммы должно передавать на
  • Генераторы:
    • Ограниченные (мелкие) сопрограммы
    • выход может возвращать управление обратно в зависимости от того, какой код вызывал генератор
  • Goroutines:
    • Нечетный гибрид совлокальных и OS-потоков
    • Невозможно прервать (например, совлокальные потоки)
    • Может выполняться параллельно в пуле потоков, связанных с управлением потоками ОС
  • Обработчики событий:
    • Процедуры/методы, вызываемые диспетчером событий в ответ на некоторые действия.
    • Очень популярен для программирования пользовательского интерфейса.
    • Не требует поддержки языка/системы; могут быть реализованы в библиотеке
    • Не более одного обработчика событий может работать одновременно; диспетчер должен дождаться, пока обработчик закончит (возврат), прежде чем начать следующий
      • Делает синхронизацию относительно простой; различные исполнения обработчиков никогда не перекрываются во времени
    • Реализация сложных задач с обработчиками событий имеет тенденцию приводить к "инвертированному потоку управления" / "копированию стека"
  • Задачи:
    • Единицы работы, которые управляются менеджером для пула работников.
    • Работники могут быть нитями, процессами или машинами
      • Конечно, вид работника, используемого библиотекой задач, оказывает значительное влияние на то, как один реализует задачи.
    • В этом списке непоследовательно и смутно используемой терминологии "задача" занимает корону. В частности, в сообществе встроенных систем "задача" иногда используется для обозначения "процесс", "поток" или "обработчик событий" (обычно называемый "службой обслуживания прерываний" ). Он также иногда используется в общих/неофициальных целях для обозначения любого типа вычислений.

Одно домашнее животное разозлилось, что я не могу остановить себя от проветривания: мне не нравится использование фразы "true concurrency" для "processor parallelism". Это довольно часто, но я думаю, что это приводит к большой путанице.

Для большинства приложений, я думаю, что основанные на задачах рамки лучше всего подходят для распараллеливания. Большинство популярных (Intel TBB, Apple GCD, Microsoft TPL и PPL) используют потоки в качестве рабочих. Мне жаль, что не было хороших альтернатив, которые использовали процессы, но я не знаю о них.

Если вас интересует concurrency (в отличие от процессора parallelism), обработчики событий являются самым безопасным способом. Совлокальные потоки - интересная альтернатива, но немного дикий запад. Пожалуйста, не используйте потоки для concurrency, если вы заботитесь о надежности и надежности вашего программного обеспечения.

Ответ 3

Protothreads - это просто реализация коммутационного случая, которая действует как конечный автомат, но делает реализацию программного обеспечения намного проще. Он основан на идее сохранения значения a и int перед меткой case и возврата, а затем возвращается к точке после случая, читая эту переменную и используя переключатель, чтобы выяснить, где продолжить. Таким образом, прототип представляет собой последовательную реализацию конечного автомата.

Ответ 4

Protothreads великолепны при реализации последовательных состояний машин. Protothreads на самом деле не являются потоками, а скорее абстракцией синтаксиса, что значительно упрощает создание машины с условием переключения/случая, которая должна последовательно переключаться между состояниями (от одного до следующего и т.д.).

Я использовал protothreads для реализации асинхронного io: http://martinschroder.se/asynchronous-io-using-protothreads/