Асинхронний проти багатопотокових - Чи є різниця?


133

Чи завжди асинхронний дзвінок створює новий потік? Яка різниця між ними?

Чи завжди асинхронний дзвінок створює чи використовує новий потік?

У Вікіпедії сказано :

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

Я знаю, що виклики асинхронізації можна робити на одних потоках? Як це можливо?



1
У JavaScript немає потоків, але він має асинхронні виклики методів.
Ajedi32

1
Будь-яка система, де один процес управляє декількома підпроцесами, процес управління може забезпечувати асинхронну роботу підпроцесів. У випадку JavaScript браузер забезпечує обчислювальний потік. Коли якась функція робить асинхронний дзвінок, браузер може зберігати контекст цієї функції. Тепер той самий потік браузера може змінити контекст, щоб відновити виконання іншої функції. В той час, як у традиційних багатопотокових програмах один потік виконує один функціональний блок, щоб дозволити іншому потоку виконувати іншу функцію. Кожна нитка виконує свою функцію синхронно.
Майк

Відповіді:


82

Це запитання є надто загальним для відповіді.

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

Асинхронний означає лише, що викликовий потік не сидить і не чекає відповіді, а також не відбувається асинхронна активність в потоці виклику.

Крім цього, вам потрібно буде більш конкретно.


7
Так що в основному я правий, кажучи: Multi-threading == Використання декількох потоків, щоб забезпечити переваги для обробки завдань, що інтенсивно працюють з процесором, які [в ідеалі] можуть отримати користь від декількох процесорів, а також вигоди в асинхронних ситуаціях. Асинхронність == процес, який робить це річ, тоді як стан, який викликав процес, не повинен чекати його завершення. (Для цього не обов'язково використовувати декілька потоків - тобто інші апаратні компоненти можуть брати на себе відповідальність).
Еван Севі

6
@Michael - Чи можете ви пояснити, як асинхронне програмування може відбуватися в одному потоці з прикладом?
Кумар Вайбхав

7
@KumarVaibhav - найпоширеніший приклад, коли один потік працює над елементами з черги (наприклад, чергу повідомлень Windows). Якщо програма має звичку надсилати елементи у власну чергу (загальний зразок), то біт коду, який надсилає елемент, не чекає завершення операції, а просто повертається. Про операцію буде забезпечено своєчасно основним контуром.
Майкл Коне

3
Існує різниця між тим, як написаний код, і тим, як він виконується. Наприклад, у C # у мене може бути метод, який запускає завдання асинхронізації, мій метод повністю знає асинхронізацію і може робити інші речі, не чекаючи завершення завдання. Однак CLR також може вирішити вбудувати своє завдання та виконати його синхронно.
Майк

яка нитка виконує очікуване завдання? метод, позначений a-sync, виконується синхронно до тих пір, поки не досягне ключового слова в очікуванні, і в цей момент, який потік виконує це завдання, що чекає?

102

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

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

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


1
Добре пояснено, Дякую; але у мене тут питання. Ви згадали, що "Наприклад, якщо операцією асинхронізації є введення / виведення, центральному процесору не потрібно чекати завершення вводу / виводу. Просто потрібно запустити операцію". Моє запитання - коли програма є однопотоковою, і скажімо, у кодовому рядку 3 ви викликаєте операцію вводу / виводу, то як можна запустити операцію в рядку 3 та виконати рядок 4, не чекаючи завершення операції вводу / виводу. ? Для мене я повинен поставити код у рядку 3 у новому потоці, щоб домогтися виконання рядка 4, не чекаючи завершення операції вводу / виводу. [Перспектива Java pgm]
людина-павук

1
Причина в тому, що хоча процесору не доведеться чекати, процесор чекатиме завершення операції вводу / виводу ... Я вважаю, що ваш другий абзац - це відповідь на мій запит. У такому випадку мені потрібно зробити висновок, що в Java асинхронні виклики потрібно виконувати в іншому потоці. Будь ласка, виправте мене, якщо я помиляюся, або дайте мені знати, чи потрібно публікувати новий SO qn
людина-павук

@spiderman Деякі мови, як-от Node.js, мають модель програмування async. Мова та час виконання забезпечують вбудовані модулі, які дозволяють виконувати рядок 4 у тому ж потоці, ще до того, як операція вводу-виводу завершиться. Це досягається за допомогою рядка 3, який забезпечує зворотний виклик, до якого час виконання буде викликатись, коли закінчення вводу-виводу буде завершено.
jrahhali

@spiderman можливо ... Функція Async ОС просто повертає помилку або щось безпосередньо.
Byeongin Yoon

18

Ні, асинхронні виклики не завжди включають потоки.

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


12

JavaScript є однопоточним і асинхронним. Наприклад, використовуючи XmlHttpRequest, ви надаєте йому функцію зворотного виклику, яка буде виконуватися асинхронно, коли відповідь повернеться.

Джон Резіг має чітке пояснення пов'язаного питання про те, як працюють таймери в JavaScript .


12

Багаторядне нанизування стосується більше однієї операції, що відбувається в одному процесі. У той час як програмування асинхронізації поширюється по процесам. Наприклад, якщо мої операції викликають веб-службу, потоці не потрібно чекати, поки веб-служба повернеться. Тут ми використовуємо програмування async, що дозволяє потоці не чекати завершення процесу на іншій машині. І коли він починає отримувати відповідь від веб-сервісу, він може перервати основний потік сказати, що веб-служба завершила обробку запиту. Тепер основна нитка може обробити результат.


Я б трохи не погодився. Я написав єдиний потоковий сервер HTTP, який обробляв декілька одночасних запитів, використовуючи завершення асинхронного вводу. Async не вимагає, щоб речі траплялися в декількох шляхах виконання, це просто означає, що декілька обчислювальних потоків можуть перекриватися. Ще один спосіб подивитися на це, що в одній потоковій ОС я можу мати 2 процеси, що працюють "одночасно". З точки зору кожного процесу, вони працюють синхронно. Однак, з точки зору ОС, він працює в режимі асинхронізації.
Майк

11

Windows завжди проводила асинхронну обробку ще з часів попередження (версії 2.13, 3.0, 3.1 та ін.) За допомогою циклу повідомлень, перш ніж підтримувати реальні потоки. Отже, щоб відповісти на ваше запитання, ні, не потрібно створювати нитку для асинхронної обробки.


@dmckee - цікаво, як різні системи розвиваються за подібними способами.
Otávio Décio

8

Асинхронні дзвінки навіть не повинні відбуватися в тій же системі / пристрої, що і той, хто викликає виклик. Отже, якщо питання полягає в тому, чи потрібен асинхронний виклик потоку в поточному процесі, відповідь - ні. Однак десь повинен бути потік виконання, який обробляє асинхронний запит.

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

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


7

Деякі системи дозволяють скористатися паралельністю в ядрі для деяких об'єктів за допомогою зворотного зв'язку. Для досить незрозумілого випадку, асинхронні зворотні виклики вводу-виводу використовувались для впровадження незаблокованих Інтернет-серверів ще в непередбачені багатозадачні дні Mac System 6-8.

Таким чином у вас є паралельні потоки виконання "in", які ви програмуєте без потоків як таких .


5

Асинхронний просто означає, що ви не блокуєте програму, яка чекає, щоб щось (виклик функції, пристрій тощо) закінчилося. Він може бути реалізований в окремому потоці, але також звичайно використовувати виділений потік для синхронних завдань і спілкуватися через якусь систему подій і таким чином досягати асинхронної поведінки.

Є приклади однопотокових асинхронних програм. Щось на зразок:

...do something
...send some async request
while (not done)
    ...do something else
    ...do async check for results

2

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

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


Це стосується деяких систем, але не всіх. Unix не вимагає від вас нерестувати або використовувати інший потік, якщо ви не назвете ядро ​​іншим потоком, я вважаю, що це один із способів переглянути його.
Craig S

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