Яка різниця між ниткою і волокном?


187

Яка різниця між ниткою і волокном? Я чув про волокна від рубіну, і я читав, що вони доступні іншими мовами, чи може хтось простим словом пояснити мені, в чому різниця між ниткою і волокном.

Відповіді:


162

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

Із потоками: поточний шлях виконання може бути перерваний або попереджений у будь-який час (зверніть увагу: цей вислів є узагальненням і не завжди може бути правдивим, залежно від ОС / пакета для нарізки даних тощо). Це означає, що для потоків цілісність даних є великою проблемою, оскільки одна нитка може бути зупинена посеред оновлення шматка даних, залишаючи цілісність даних у поганому або неповному стані. Це також означає, що операційна система може скористатися декількома процесорами та процесорними ядрами, запустивши більше одного потоку одночасно і залишаючи його розробнику для захисту доступу до даних.

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


7
Чи є спосіб використовувати кілька потоків для виконання волокон паралельно?
Бараде

2
@Jason, коли ви заявляєте ~ "з волокнами, поточний шлях виконання переривається лише тоді, коли волокно дасть виконання" і "волокна завжди починаються та зупиняються у чітко визначених місцях, так що цілісність даних набагато менше проблеми", Ви маєте на увазі, що при спільному використанні змінних нам не потрібно використовувати "механізми блокування" та мінливі змінні? Або ти маєш на увазі, що нам ще потрібно робити це?
Pacerier

@ Baradé Це цікаве питання, ти знайшов відповідь?
Mayur

57

Нитки використовують попереднє планування, тоді як волокна використовують кооперативне планування.

За допомогою потоку керуючий потік може перерватися в будь-який час, і інша нитка може перейняти. З декількома процесорами ви можете мати декілька потоків, які працюють одночасно ( одночасне багатопотокове чи SMT). Як результат, ви повинні бути дуже обережними щодо паралельного доступу до даних та захищати свої дані за допомогою мутексів, семафорів, змінних умов тощо. Часто буває дуже хитро правильно.

За допомогою волокна керування перемикається лише тоді, коли ви повідомляєте про це, як правило, за допомогою виклику функції, названого чимось на кшталт yield(). Це полегшує одночасний доступ до даних, оскільки вам не доведеться турбуватися про атомність структур даних або мутексів. Поки ви не поступаєтесь, немає жодної небезпеки бути викритим і мати інше волокно, яке намагається прочитати чи змінити дані, з якими ви працюєте. Однак, якщо ваше волокно потрапить у нескінченний цикл, жодне інше волокно не може працювати, оскільки ви не поступаєтеся.

Можна також змішувати нитки і волокна, що спричиняє проблеми, з якими стикаються обидва. Не рекомендується, але іноді це можна зробити правильно, якщо зробити це ретельно.


3
Я думаю, що нескінченний цикл - це лише помилка, яку потрібно виправити, і нитки мають лише досить неясну перевагу, коли існує нескінченний цикл. Пов'язана концепція, що не стосується помилок, - це коли тривалий процес, який користувач може скасувати. У цьому випадку, використовуючи нитки або волокна, тривалий процес повинен бути спільним - просто вбивання його потоку може залишити деякі ваші структури даних заплутані, тому один кращий спосіб - наприклад, тривалий потік процесу періодично перевірятиметься якби вона була перервана. Це не так сильно відрізняється від волокна, яке періодично дає урожай.
Євгеній Сергеєв

43

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

Наслідки полягають у тому, що волокна дешевші і що додаток має більше контролю над плануванням. Це може бути важливо, якщо додаток створює безліч одночасних завдань та / або хоче тісно оптимізувати їх запуск. Наприклад, сервер бази даних може скористатися волокнами, а не потоками.

(Можуть бути й інші звичаї на той самий термін; як зазначалося, це визначення Win32.)


37

Спершу я б рекомендував прочитати це пояснення про різницю між процесами та потоками як фоновим матеріалом.

Після того, як ви прочитали, що це досить прямо вперед. Банки з нитками можуть бути реалізовані або в ядрі, в просторі користувача, або два можна змішати. Волокна - це в основному потоки, реалізовані в просторі користувача.

  • Як правило, називається потік - це потік виконання, реалізований в ядрі: відомий як потік ядра. Планування потоку ядра обробляється виключно ядром, хоча потік ядра може добровільно звільнити процесор, сплячи, якщо захоче. Перевага ядра має перевагу в тому, що вона може використовувати блокуючи введення / виведення та нехай ядро ​​турбується про планування. Основним недоліком є ​​те, що комутація потоку відбувається досить повільно, оскільки вимагає захоплення ядра.
  • Волокна - це потоки користувальницького простору, планування яких обробляється в просторі користувача однією або кількома потоками ядра в рамках одного процесу. Це робить комутацію волокон дуже швидкою. Якщо ви згрупуєте всі волокна, що мають доступ до певного набору спільних даних у контексті однієї нитки ядра, і їх планування обробляється однією потоком ядра, то ви можете усунути проблеми синхронізації, оскільки волокна будуть ефективно працювати послідовно, і у вас є повна контроль за їх плануванням. Групування пов'язаних волокон під однією ниткою ядра є важливою, оскільки ядро ​​ядра може бути попередньо спотворене ядром. Цей пункт не з’ясовується у багатьох інших відповідях. Крім того, якщо ви використовуєте блокування вводу / виводу у волокні, весь потік ядра є частиною блоків, включаючи всі волокна, що входять до цієї нитки ядра.

У розділі 11.4 "Процеси та нитки в Windows Vista" в Сучасних операційних системах Tanenbaum зауважує:

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


4
Це найповніша відповідь.
Бернар

12

Зауважте, що на додаток до потоків і волокон Windows 7 вводить планування в режимі користувача :

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

Більше інформації про нитки, волокна та UMS можна отримати, переглянувши Дейва Проберта: Всередині Windows 7 - Планувальник режимів користувача (UMS) .


7

Нитки заплановані ОС (попередньо). Нитка може бути зупинена або відновлена ​​в будь-який час ОС, але волокна більш-менш управляють собою (кооперативно) і поступаються один одному. Тобто, програміст контролює, коли волокна проводять їх обробку і коли ця обробка переходить на інше волокно.


7

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

Деякі корисні посилання, що пояснюють це краще, ніж я, мабуть, це:


7

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

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


3

Визначення волокна Win32 насправді є визначенням "Зеленої нитки", створеним в Sun Microsystems. Немає необхідності витрачати термін волокно на якийсь потік, тобто потік, що виконується в просторі користувача під контролем коду користувача / бібліотеки потоків.

Для уточнення аргументу дивіться наступні коментарі:

  • Завдяки гіпертоці, багатоядерний процесор може приймати кілька потоків і розподіляти їх по одному на кожному ядрі.
  • Суперскалярний конвеєрний конвеєр приймає один потік для виконання і використовує паралелізм рівня інструкцій (ILP) для швидшого запуску потоку. Можна припустити, що одна нитка розривається на паралельні волокна, що проходять в паралельних трубопроводах.
  • SMT CPU може приймати кілька потоків і гальмувати їх у інструментальних волокнах для паралельного виконання на декількох конвеєрах, використовуючи трубопроводи ефективніше.

Ми повинні припустити, що процеси складаються з ниток і що нитки повинні бути виготовлені з волокон. Маючи на увазі цю логіку, неправильне використання волокон для інших видів ниток.


Це цікаво.
JSON
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.