Asynchroniczność a wielowątkowość - czy jest jakaś różnica?

134

Czy wywołanie asynchroniczne zawsze tworzy nowy wątek? Jaka jest różnica między nimi?

Czy wywołanie asynchroniczne zawsze tworzy lub używa nowego wątku?

Wikipedia mówi :

W programowaniu komputerowym zdarzenia asynchroniczne to takie, które występują niezależnie od głównego przepływu programu. Akcje asynchroniczne to akcje wykonywane w schemacie nieblokującym, które pozwalają głównemu przepływowi programu kontynuować przetwarzanie.

Wiem, że połączenia asynchroniczne można wykonywać na pojedynczych wątkach? Jak to jest możliwe?

Ted Smith
źródło
1
JavaScript nie ma wątków, ale ma asynchroniczne wywołania metod.
Ajedi32
1
W każdym systemie, w którym jeden proces zarządza wieloma podprocesami, proces sterowania może zapewnić asynchroniczne działanie podprocesów. W przypadku JavaScript przeglądarka zapewnia strumień obliczeniowy. Gdy jakaś funkcja wykonuje wywołanie asynchroniczne, przeglądarka może przechowywać kontekst dla tej funkcji. Teraz ten sam pojedynczy wątek przeglądarki może zmienić kontekst, aby wznowić wykonywanie innej funkcji. Podczas gdy w tradycyjnych programach wielowątkowych jeden wątek wykonuje jeden blok funkcyjny, aby umożliwić drugiemu wątkowi wykonanie innej funkcji. Każdy wątek synchronicznie wykonuje swoją własną funkcję.
Mike

Odpowiedzi:

83

To pytanie jest cholernie zbyt ogólne, aby odpowiedzieć.

W ogólnym przypadku wywołanie asynchroniczne niekoniecznie tworzy nowy wątek. To jeden ze sposobów implementacji, z istniejącą wcześniej pulą wątków lub procesem zewnętrznym. Zależy to w dużym stopniu od języka, modelu obiektowego (jeśli istnieje) i środowiska wykonawczego.

Asynchroniczny oznacza po prostu, że wątek wywołujący nie siedzi i nie czeka na odpowiedź, ani działanie asynchroniczne nie występuje w wątku wywołującym.

Poza tym będziesz musiał uzyskać bardziej szczegółowe informacje.

Michael Kohne
źródło
7
Zasadniczo mam rację, mówiąc: wielowątkowość == Używanie wielu wątków w celu zapewnienia korzyści przetwarzania w zadaniach intensywnie wykorzystujących procesor, które [idealnie] mogą korzystać z wielu procesorów, a także korzyści w sytuacjach asynchronicznych. Asynchronia == proces, który robi swoje, podczas gdy stan, który wywołał proces, nie musi czekać na jego zakończenie. (Może niekoniecznie używać do tego wielu wątków - tj. Inne komponenty sprzętowe mogą brać na siebie odpowiedzialność).
Evan Sevy
6
@Michael - Czy mógłbyś wyjaśnić na przykładzie, jak programowanie asynchroniczne może mieć miejsce w jednym wątku?
Kumar Vaibhav
7
@KumarVaibhav - najczęstszym przykładem jest sytuacja, gdy pojedynczy wątek działa na elementach z kolejki (na przykład kolejka komunikatów systemu Windows). Jeśli program ma zwyczaj wysyłania elementów do swojej własnej kolejki (wspólny wzorzec), to bit kodu, który wysyła element, nie czeka na zakończenie operacji, ale po prostu zwraca. Operacją zajmie się w odpowiednim czasie główna pętla.
Michael Kohne
3
Może istnieć różnica między sposobem pisania kodu a jego wykonywaniem. Na przykład w języku C # mogę mieć metodę, która uruchamia zadanie asynchroniczne, moja metoda jest w pełni świadoma asynchroniczności i może wykonywać inne czynności bez czekania na zakończenie zadania. Jednak środowisko CLR może również zdecydować o wbudowaniu mojego zadania i wykonaniu go synchronicznie.
Mike
który wątek wykonuje oczekiwane zadanie? metoda oznaczona jako a-sync jest wykonywana synchronicznie, aż osiągnie słowo kluczowe await, który wątek w tym momencie wykonuje to oczekiwane zadanie?
103

Zawsze, gdy operacja, która musi być wykonywana asynchronicznie, nie wymaga pracy procesora, można ją wykonać bez tworzenia kolejnego wątku. Na przykład, jeśli operacja asynchroniczna to I / O, CPU nie musi czekać na zakończenie I / O. Wystarczy rozpocząć operację, a następnie może przejść do innej pracy, podczas gdy sprzęt we / wy (kontroler dysku, interfejs sieciowy itp.) Działa we / wy. Sprzęt informuje procesor o zakończeniu, przerywając działanie procesora, a system operacyjny dostarcza zdarzenie do aplikacji.

Często abstrakcje wyższego poziomu i interfejsy API nie uwidaczniają bazowe asynchroniczne interfejsy API dostępne w systemie operacyjnym i podstawowym sprzęcie. W takich przypadkach zwykle łatwiej jest tworzyć wątki do wykonywania operacji asynchronicznych, nawet jeśli spawnowany wątek tylko czeka na operację we / wy.

Jeśli operacja asynchroniczna wymaga działania procesora, to generalnie operacja ta musi odbywać się w innym wątku, aby była naprawdę asynchroniczna. Nawet wtedy będzie to naprawdę asynchroniczne tylko wtedy, gdy będzie więcej niż jedna jednostka wykonawcza.

karunski
źródło
1
Dobrze wyjaśnione, dziękuję; ale mam pytanie. Wspomniałeś, że „Na przykład, jeśli operacja asynchroniczna to I / O, CPU nie musi czekać na zakończenie I / O. Wystarczy, że rozpocznie operację”. Moje pytanie brzmi: kiedy program jest jednowątkowy i mówimy w linii kodu 3, wywołujesz operację we / wy, a następnie jak możesz rozpocząć operację w linii 3 i wykonać linię 4 bez czekania na zakończenie operacji we / wy ? Dla mnie muszę umieścić kod w linii 3 w nowym wątku, aby linia 4 została wykonana bez czekania na zakończenie operacji we / wy. [Perspektywa Java pgm]
spiderman
1
powodem jest to, że chociaż procesor nie musi czekać, procesor będzie czekał na zakończenie operacji we / wy ... Myślę, że Twój drugi akapit jest odpowiedzią na moje pytanie. W takim przypadku muszę stwierdzić, że w Javie asynchroniczne wywołania muszą być wykonywane w innym wątku. Proszę mnie poprawić, jeśli się mylę, lub daj mi znać, jeśli muszę opublikować nowy SO qn
spiderman
@spiderman Niektóre języki, takie jak Node.js, mają asynchroniczny model programowania. Język i środowisko wykonawcze zapewniają wbudowane funkcje, które umożliwiają wykonanie linii 4 w tym samym wątku, nawet przed zakończeniem operacji we / wy. Osiąga się to przez linię 3 zapewniającą wywołanie zwrotne, które środowisko wykonawcze wywoła po zakończeniu operacji we / wy.
jrahhali
@spiderman może ... funkcja Async systemu operacyjnego po prostu zwraca fałsz lub coś bezpośrednio.
Byeongin Yoon,
18

Nie, wywołania asynchroniczne nie zawsze obejmują wątki.

Zazwyczaj rozpoczynają jakąś operację, która jest kontynuowana równolegle z rozmówcą. Ale ta operacja może być obsługiwana przez inny proces, przez system operacyjny, przez inny sprzęt (np. Kontroler dysku), przez inny komputer w sieci lub przez człowieka. Wątki nie są jedynym sposobem na równoległe wykonywanie zadań.

Jason Orendorff
źródło
12

JavaScript jest jednowątkowy i asynchroniczny. Na przykład, gdy używasz XmlHttpRequest, udostępniasz mu funkcję wywołania zwrotnego, która zostanie wykonana asynchronicznie po zwróceniu odpowiedzi.

John Resig dobrze wyjaśnia powiązany problem z działaniem liczników czasu w JavaScript .

George V. Reilly
źródło
12

Wielowątkowość odnosi się do więcej niż jednej operacji wykonywanej w tym samym procesie. Podczas gdy programowanie asynchroniczne rozprzestrzenia się między procesami. Na przykład, jeśli moje operacje wywołują usługę internetową, wątek nie musi czekać na powrót usługi sieciowej. Tutaj używamy programowania asynchronicznego, które pozwala wątkowi nie czekać na zakończenie procesu na innej maszynie. A kiedy zacznie otrzymywać odpowiedź z usługi sieciowej, może przerwać główny wątek, aby powiedzieć, że usługa internetowa zakończyła przetwarzanie żądania. Teraz główny wątek może przetworzyć wynik.

Murugan Gopalan
źródło
Trochę bym się nie zgodził. Napisałem pojedynczy wątkowy serwer HTTP, który obsługiwał wiele jednoczesnych żądań przy użyciu asynchronicznego uzupełniania we / wy. Async nie wymaga, aby coś działo się na wielu ścieżkach wykonania, oznacza to po prostu, że wiele strumieni obliczeniowych może się nakładać. Innym sposobem spojrzenia na to jest to, że w jednym wątkowym systemie operacyjnym mogę mieć 2 procesy działające „jednocześnie”. Z punktu widzenia każdego procesu działają one synchronicznie. Jednak z punktu widzenia systemu operacyjnego działa asynchronicznie.
Mike
11

Windows zawsze miał przetwarzanie asynchroniczne od czasów nie wywłaszczających (wersje 2.13, 3.0, 3.1 itd.) Przy użyciu pętli komunikatów, na długo przed obsługą rzeczywistych wątków. Aby odpowiedzieć na twoje pytanie, nie, nie jest konieczne tworzenie wątku do wykonywania asynchronicznego przetwarzania.

Otávio Décio
źródło
@dmckee - ciekawe, jak różne systemy ewoluują w podobny sposób.
Otávio Décio
8

Asynchroniczne wywołania nie muszą nawet występować w tym samym systemie / urządzeniu, co wywoływane. Jeśli więc pytanie brzmi, czy wywołanie asynchroniczne wymaga wątku w bieżącym procesie, odpowiedź brzmi: nie. Jednak musi istnieć wątek wykonywania gdzieś przetwarzający żądanie asynchroniczne.

Wątek wykonania to niejasny termin. We współpracujących systemach zadań, takich jak wczesne Macintosh i Windows OS, wątek wykonania może być po prostu tym samym procesem, który spowodował, że żądanie uruchomiło inny stos, wskaźnik instrukcji itp. Jednak gdy ludzie ogólnie mówią o wywołaniach asynchronicznych , zazwyczaj oznaczają wywołania, które są obsługiwane przez inny wątek, jeśli jest to proces wewnątrzprocesowy (tj. w ramach tego samego procesu) lub przez inny proces, jeśli jest to proces międzyprocesowy.

Należy zauważyć, że komunikacja międzyprocesowa (lub międzyprocesowa) (IPC) jest powszechnie uogólniana w celu uwzględnienia komunikacji wewnątrzprocesowej, ponieważ techniki blokowania i synchronizacji danych są zwykle takie same, niezależnie od tego, w jakim procesie działają oddzielne wątki wykonania.

Mikrofon
źródło
7

Niektóre systemy pozwalają na wykorzystanie współbieżności jądra dla niektórych funkcji przy użyciu wywołań zwrotnych. W raczej mało znanym przypadku asynchroniczne wywołania zwrotne we / wy zostały użyte do zaimplementowania nieblokujących serwerów internetowych w czasach wielozadaniowości bez wywłaszczania w systemie Mac System 6-8.

W ten sposób masz współbieżne strumienie wykonywania „w” programie bez wątków jako takich .

dmckee --- kociak ex-moderator
źródło
5

Asynchroniczny oznacza po prostu, że nie blokujesz programu czekającego na zakończenie (wywołanie funkcji, urządzenie itp.). Można go zaimplementować w osobnym wątku, ale często używa się dedykowanego wątku do zadań synchronicznych i komunikuje się za pośrednictwem pewnego rodzaju systemu zdarzeń, uzyskując w ten sposób zachowanie podobne do asynchronicznego.

Istnieją przykłady jednowątkowych programów asynchronicznych. Coś jak:

...do something
...send some async request
while (not done)
    ...do something else
    ...do async check for results
Milan Babuškov
źródło
2

Charakter połączeń asynchronicznych jest taka, że jeśli chcesz, aby aplikacja nadal działa, gdy rozmowa jest w toku, to albo trzeba tarło nowy wątek, a przynajmniej wykorzystać inny wątek, że zostały stworzone wyłącznie dla celów obsługa asynchronicznych wywołań zwrotnych.

Czasami, w zależności od sytuacji, możesz chcieć wywołać metodę asynchroniczną, ale sprawić, by wyglądała ona na użytkownika jako synchroniczna (tj. Blokuj, dopóki metoda asynchroniczna nie zasygnalizuje, że została zakończona). Można to osiągnąć za pomocą interfejsów API Win32, takich jak WaitForSingleObject .

LeopardSkinPillBoxHat
źródło
Dotyczy to niektórych systemów, ale nie wszystkich. Unix nie wymaga od ciebie tworzenia lub używania innego wątku, chyba że wywołasz jądro innym wątkiem, co, jak sądzę, jest jednym ze sposobów spojrzenia na to.
Craig S
Nie dotyczy to również systemu Windows. Na przykład nakładające się operacje we / wy są asynchroniczne.
Jason Orendorff