В чем разница между ниткой и волокном?

187

В чем разница между ниткой и волокном? Я слышал о волокнах от ruby ​​и читал, что они доступны на других языках, может кто-нибудь объяснить мне в простых терминах, в чем разница между нитью и волокном.

tatsuhirosatou
источник

Ответы:

163

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

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

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

Джейсон Коко
источник
7
Есть ли способ использовать несколько потоков для параллельного выполнения волокон?
Бараде
2
@Jason, Когда вы говорите ~ «с волокнами, текущий путь выполнения прерывается только тогда, когда волокно приводит к выполнению», а «волокна всегда запускаются и останавливаются в четко определенных местах, поэтому целостность данных гораздо менее важна», Вы имеете в виду, что при совместном использовании переменных нам не нужно использовать «механизмы блокировки» и переменные переменные? Или вы имеете в виду, что нам все еще нужно делать эти вещи?
Pacerier
@ Baradé Это интересный вопрос, ты нашел ответ?
Mayur
57

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

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

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

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

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

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

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

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

itowlson
источник
37

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

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

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

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

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

Роберт С. Барнс
источник
4
Это самый полный ответ.
Бернард
12

Обратите внимание, что в дополнение к потокам и волокнам в Windows 7 вводится планирование в режиме пользователя :

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

Дополнительную информацию о потоках, волокнах и UMS можно найти в Dave Probert: Внутри Windows 7 - Планировщик пользовательских режимов (UMS) .

Грант Вагнер
источник
7

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

Арнольд Спенс
источник
7

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

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

Майк Лоуэн
источник
7

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

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

paxdiablo
источник
3

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

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

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

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

billmic
источник
Это интересно.
JSON