Потоки проти Async


82

Я читав про потокову модель програмування проти асинхронної моделі з цієї справді гарної статті. http://krondo.com/blog/?p=1209

Однак у статті згадуються такі моменти.

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

Я пам’ятаю, як читав, що потоки управляються операційною системою, переміщаючись між TCB між Ready-Queue і Waiting-Queue (серед інших черг). У цьому випадку потоки не витрачають час на очікування, так само як і вони?

У світлі вищезазначеного, які переваги асинхронних програм перед різьбовими програмами?


5
Ні, я мав на увазі Threaded проти Async. Я згадав пункт перший лише тому, що це було те, що я зрозумів із статті.

Відповіді:


78
  1. Дуже складно написати код, який є безпечним для потоку. З асинхронним кодом ви точно знаєте, де код перейде від одного завдання до іншого, і тому умови змагання набагато важче отримати.
  2. Потоки споживають достатню кількість даних, оскільки кожен потік повинен мати свій власний стек. З асинхронним кодом весь код використовує один і той самий стек, і стек залишається невеликим завдяки постійному розкручуванню стека між завданнями.
  3. Потоки - це структури ОС, і тому вони мають більше пам'яті для підтримки платформи. З асинхронними завданнями такої проблеми немає.

12
Щоб трохи детально розробити: 1. Частина вводу / виводу потокового коду відносно проста, але управління спільним станом між потоками (за допомогою блокування / черг / тощо) без расових умов робить це складним. Використання асинхронної моделі означає, що у вас менше відбувається одночасно, тому легко уникнути перегонів. 2/3. кожен потік буде споживати принаймні одну сторінку пам'яті стека (зазвичай 4 КБ або 8 КБ), а також деякий невідомий обсяг пам'яті для інших структур даних, пов'язаних із станом цього потоку.
Добес Вандермеер,

12

Існує два способи створення потоків:

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

асинхронна різьблення - батьки та діти виконують паралельно / незалежно один від одного. Багатопотокові сервери зазвичай слідують цій моделі.

ресурс - http://www.amazon.com/Operating-System-Concepts-Abraham-Silberschatz/dp/0470128720


7
  1. Припустимо, у вас є 2 завдання, які не включають жодного вводу-виводу (на багатопроцесорній машині). У цьому випадку потоки перевершують Async. Оскільки Async, як одна різьбова програма, виконує ваші завдання по порядку. Але потоки можуть виконувати обидва завдання одночасно.

  2. Припустимо, у вас є 2 завдання, які включають введення-виведення (на багатопроцесорній машині). У цьому випадку як Async, так і Threads виконують більш-менш однакові дії (продуктивність може змінюватися залежно від кількості ядер, планування, обсягу процесів, що вимагає завдання тощо). Крім того, Async вимагає меншої кількості ресурсів, невеликих накладних витрат і менш складних програм для багатопотокової програми.

Як це працює? Потік 1 виконує Завдання 1, оскільки він очікує на введення-виведення, він переміщується до черги очікування на введення-виведення. Подібним чином Thread 2 виконує Завдання 2, оскільки він також включає введення-виведення, він переміщується до черги очікування вводу-виводу. Як тільки його запит вводу-виводу вирішено, він переміщується до готової черги, щоб планувальник міг запланувати виконання потоку.

Async виконує завдання 1 і, не чекаючи завершення введення-виведення, продовжує з завданням 2, потім чекає завершення вводу-виводу обох завдань. Він виконує завдання в порядку виконання IO.

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

У наведеному нижче відео пояснюється, Async vs Threaded modelа також коли використовувати тощо, https://www.youtube.com/watch?v=kdzL3r-yJZY

Сподіваюся, це корисно.


2
Посилання на потенційне рішення завжди вітається, але, будь ласка, додайте контекст навколо посилання, щоб ваші однодумці мали певне уявлення, що це таке і чому воно існує. Завжди цитуйте найбільш релевантну частину важливого посилання, якщо цільовий сайт недоступний або залишається назавжди поза мережею. Візьміть до уваги, що ледве більше ніж посилання на зовнішній сайт - це можлива причина, чому і як видаляються деякі відповіді? .
Machavity

4

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

Коли потік закінчить чекати чогось, скажімо введення / виведення, це можна вважати запущеним. Потоки, які можна запускати, незабаром будуть заплановані до виконання. Чи буде це реалізовано як проста черга чи щось більш досконале, це, знову ж таки, залежить від ОС та обладнання. Ви можете розглядати набір заблокованих потоків як набір, а не як строго впорядковану чергу.

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


0

Async I / O означає, що у драйвері вже є потік, який виконує цю роботу, тому ви дублюєте функціональні можливості та створюєте певні накладні витрати. З іншого боку, часто не задокументовано, як саме поводиться потік драйвера, і в складних сценаріях, коли ви хочете контролювати поведінку очікування / скасування / запуску / зупинки, синхронізацію з іншими потоками, має сенс реалізувати власний потік. Також іноді легше міркувати в термінах синхронізації.


5
Це зовсім не так, як працює асинхронний ввід-вивід. По суті, введення / виведення керується подіями (ви ініціюєте введення / виведення на пристрій, пізніше пристрій завершує його і, сподіваємось, повідомляє вам це з перериванням). Існують деякі види вводу-виводу (наприклад, введення / виведення на диску), коли драйвер використовує потік ядра з дещо незрозумілих причин; але для мереж це асинхронні операції аж донизу.
Гліф

0

див. http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling

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

Відповідно до цього, весь ваш процес може бути заблокований, і жоден потік не планується, коли один потік заблокований в IO. Я думаю, що це специфічно для ОС і не завжди буде дотримуватися.

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