2009-04-28 2 views

ответ

120

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

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

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

+5

Есть ли способ использовать несколько потоков для параллельного выполнения волокон? –

+1

@Jason, когда вы указываете ~ "с волокнами, текущий путь выполнения прерывается только тогда, когда волокно дает выполнение", и "волокна всегда начинаются и останавливаются в четко определенных местах, поэтому целостность данных намного меньше проблемы", вы имеете в виду что при совместном использовании переменных нам не нужно использовать «блокирующие механизмы» и изменчивые переменные? Или вы имеете в виду, что нам все еще нужно делать эти вещи? – Pacerier

42

В Win32 волокно представляет собой своего рода управляемую пользователями нить. У волокна есть свой собственный стек и его собственный указатель инструкций и т. Д., Но волокна не назначаются ОС: вы должны явно вызвать SwitchToFiber. Потоки, напротив, предварительно запланированы системой операций. Так грубо говоря, волокно - это поток, который управляется на уровне приложения/времени выполнения, а не является истинным потоком ОС.

Последствия того, что волокна дешевле и что приложение имеет больший контроль над планированием. Это может быть важно, если приложение создает множество параллельных задач и/или хочет оптимизировать их при запуске. Например, сервер базы данных может выбрать использование волокон, а не потоков.

(Там могут быть и другие примеры использования того же термина, как уже отмечалось, это определение Win32.)

7

Нити запланированы на ОС (упреждающий). Нить может быть остановлена ​​или возобновлена ​​в любое время ОС, но волокна более или менее управляются (совместно) и уступают друг другу. То есть программист контролирует, когда волокна выполняют свою обработку, и когда эта обработка переключается на другое волокно.

5

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

Некоторые полезные ссылки объясняющие это лучше, чем я, вероятно, сделал это:

42

Нитки использовать упреждающий планирования, в то время как волокна используют кооператив scheduli нг.

С потоком поток управления может быть прерван в любое время, и другой поток может взять верх. С несколькими процессорами вы можете одновременно работать с несколькими потоками (одновременно многопоточность или SMT). В результате вы должны быть очень заботиться о параллельном доступе к данным и защищать свои данные с помощью мьютексов, семафоров, переменных условий и т. Д. Часто очень сложно получить право.

С волокном управление только переключается, когда вы говорите об этом, как правило, с вызовом функции с именем что-то вроде yield(). Это упрощает одновременный доступ к данным, поскольку вам не нужно беспокоиться об атомарности структур данных или мьютексов. До тех пор, пока вы не уступаете, нет опасности быть выгруженным и другим волокном, пытающимся прочитать или изменить данные, с которыми вы работаете. В результате, однако, если ваше волокно попадает в бесконечный цикл, никакое другое волокно не может работать, поскольку вы не уступаете.

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

+2

Я думаю, что бесконечный цикл - это всего лишь ошибка, которая должна быть исправлена, а потоки имеют довольно неясное преимущество, когда есть бесконечный цикл. Связанная не-багги концепция - это когда существует длительный процесс, который пользователь может пожелать отменить. В этом случае, независимо от того, используете ли вы нити или волокна, длительный процесс должен быть совместным - просто уничтожение его потока может привести к тому, что некоторые из ваших структур данных будут испорчены, поэтому лучший способ - это, например, длительный поток процесса будет периодически проверяться, если он был прерван. Это не так сильно отличается от волокна, получаемого периодически. –

6

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

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

12

Обратите внимание, что в дополнении к нити и волокну, Windows 7 представляет User-Mode Scheduling:

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

Более подробную информацию о резьбах, волокнах и UMS можно получить, просмотрев Dave Probert: Inside Windows 7 - User Mode Scheduler (UMS).

30

Прежде всего, я рекомендую прочитать это объяснение the difference between processes and threads в качестве справочного материала.

Как только вы прочтете, что это довольно прямолинейно. Режимы потоков могут быть реализованы либо в ядре, либо в пользовательском пространстве, либо два могут быть смешаны. Волокна - это в основном потоки, реализованные в пространстве пользователя.

  • То, что обычно называют потоком, представляет собой поток выполнения, реализованный в ядре: то, что известно как поток ядра. Планирование потока ядра обрабатывается исключительно ядром, хотя поток ядра может добровольно освобождать CPU, если он хочет. Преимущество ядра в том, что он может использовать блокирующий ввод-вывод и позволяет ядру беспокоиться о планировании. Основным недостатком является то, что переключение потоков относительно медленное, так как оно требует захвата ядра.
  • Волокна представляют собой потоки пользовательского пространства, планирование которых обрабатывается в пространстве пользователя одним или несколькими потоками ядра под одним процессом. Это делает переключение волокон очень быстрым. Если вы группируете все волокна, получающие доступ к определенному набору общих данных, в контексте одного потока ядра, и их планирование обрабатывается одним потоком ядра, тогда вы можете устранить проблемы синхронизации, так как волокна будут эффективно запускаться в последовательном режиме и у вас есть контролировать их планирование. Группировка связанных волокон под одним потоком ядра важна, так как поток ядра, в котором они запущены, может быть предварительно упущен ядром. Во многих других ответах этот момент не уточняется. Кроме того, если вы используете блокирующий ввод-вывод в волокне, весь поток ядра является частью блоков, включая все волокна, которые являются частью этого потока ядра.

В разделе 11.4 «Процессы и потоки в Windows Vista» в операционных системах Современных, Таненбаум комментарии:

Хотя волокна совместно запланированы, если есть несколько нитей диспетчеризации волокон, много тщательная синхронизация необходима для обеспечения того, чтобы волокна не мешали друг другу. Для упростить взаимодействие между потоками и волокнами, часто полезно создавать только столько потоков, сколько есть процессоров для запуска , и аффинизировать потоки для каждого запуска только на определенном наборе доступных процессоров или даже просто один процессор. Каждый поток может затем запускать конкретное подмножество волокон, устанавливая связь между нитями и волокнами, которая упрощает синхронизацию . Тем не менее, есть еще много проблем с волокнами . Большинство библиотек Win32 полностью не знают волокон, и приложения, которые пытаются использовать волокна, как если бы они были потоками, будут сталкиваются с различными сбоями. Ядро не знает волокон, , и когда волокно входит в ядро, поток, который он выполняет, может содержать блок , а ядро ​​будет планировать произвольный поток на процессоре , что делает его недоступным для запуска других волокон. Для этих причины волокна используются редко, за исключением случаев, когда они переносят код из других систем , которые явно нуждаются в функциональности, предоставляемой волокнами.

+3

Это самый полный ответ. – Alkaline

1

Определение волокна Win32 на самом деле является «зеленой темой», установленной в Sun Microsystems. Нет необходимости тратить термин «волокно» на нить какого-либо типа, т. Е. Поток, выполняющийся в пользовательском пространстве под управлением пользовательского кода/управления потоковыми библиотеками.

Чтобы прояснить аргумент взгляд на следующие замечания:

  • с Hyper-Threading, многоядерные CPU может принимать несколько потоков и распределить их по одному на каждом ядре.
  • Суперскалярный конвейерный процессор принимает один поток для выполнения и использует Параллельность уровня инструкций (ILP) для быстрого запуска потока.Мы можем предположить, что один поток разбит на параллельные волокна, работающие в параллельных трубопроводах.
  • Процессор SMT может принимать несколько потоков и тормозить их в волокна инструкций для параллельного исполнения на нескольких трубопроводах, используя трубопроводы более эффективно.

Мы должны предположить, что процессы выполнены из нитей, и эти нити должны быть выполнены из волокон. С учетом этой логики использование волокон для других сортов нитей является неправильным.

0

A Fiber - это легкая нить, которая использует совместную многозадачность вместо упреждающей многозадачности. Бегущее волокно должно явно «уступать», чтобы позволить другому волокну работать, что делает их реализацию намного проще, чем потоки ядра или пользователя.

Coroutine - это компонент, который обобщает подпрограмму, позволяющую несколько точек входа для приостановки и возобновления выполнения в определенных местах. В отличие от подпрограмм, сопрограммы могут выйти, вызывая другие сопрограммы, которые позже могут вернуться к точке, где они были вызваны в исходной сопрограмме.

Смежные вопросы