Я несколько раз использовал "потоки" perl. Они наиболее полезны для запуска какого-либо процесса и продолжения чего-то другого. У меня нет большого опыта в теории того, как они работают под капотом, но у меня есть большой практический опыт программирования с ними.
Например, у меня есть серверный поток, который прослушивает входящие сетевые соединения и выдает ответ о состоянии, когда кто-то просит об этом. Я создаю этот поток, затем продолжаю и создаю другой поток, который контролирует систему, проверяет пять элементов, спит несколько секунд и снова зацикливается. Сбор данных монитора может занять 3-4 секунды, затем он помещается в общую переменную, и серверный поток может прочитать это при необходимости и сразу же вернуть последний известный результат тому, кто запросит. Поток монитора, когда обнаруживает, что элемент находится в плохом состоянии, запускает отдельный поток для восстановления этого элемента. Затем он движется дальше, проверяя другие элементы, пока ремонтируется плохой, и отбрасывая другие потоки на наличие других плохих элементов или присоединяясь к законченным ремонтным нитям. Основная программа все время зацикливается каждые несколько секунд, следя за тем, чтобы потоки монитора и сервера не были присоединены / работали. Все это может быть написано как группа отдельных программ, использующих какую-то другую форму IPC, но потоки perl делают это простым.
Другое место, где я их использовал, - это генератор фракталов. Я разделил бы части изображения, используя некоторый алгоритм, и затем запустил бы столько потоков, сколько у меня есть процессоров для выполнения работы. Каждый из них складывал свои результаты в один объект GD, что не вызывало проблем, поскольку каждый из них работал над разными частями массива, а затем, когда все было готово, я выписывал изображение GD. Это было мое введение в использование потоков perl, и это было хорошее введение, но затем я переписал его на C, и это было на два порядка быстрее :-). Затем я переписал свою версию на Perl с использованием Inline :: C, и она была только на 20% медленнее, чем версия на чистом C. Тем не менее, в большинстве случаев, когда вы хотите использовать потоки из-за нагрузки на процессор, вам, вероятно, нужно просто выбрать другой язык.
Как уже упоминалось, ветвь и нити действительно перекрываются для многих целей. Однако Coro на самом деле не допускает многопроцессорное использование или параллельную обработку, как это делают ветвь и нить, вы будете когда-либо видеть свой процесс только на 100%. Я слишком упрощаю это, но я думаю, что самый простой способ описать Coro - это планировщик для ваших подпрограмм. Если у вас есть подпрограмма, которая блокирует, вы можете переходить к другому и делать что-то еще, пока вы ждете, например, у вас есть приложение, которое вычисляет результаты и записывает их в файл. Один блок может вычислить результаты и вставить их в канал. Когда работа заканчивается, другой блок начинает записывать их на диск. Пока этот блок ожидает на диске, другой блок может снова начать вычислять результаты, если он получит больше работы. По общему признанию я не сделал много с Коро; это звучит как хороший способ ускорить некоторые вещи, но я немного расстроен тем, что не могу сделать две вещи одновременно.
Мое личное предпочтение, если я хочу сделать многопроцессорность, это использовать fork, если я делаю много маленьких или коротких вещей, потоков для нескольких больших или долгоживущих вещей.