Tak. Korzystanie z kolejki szeregowej zapewnia seryjne wykonywanie zadań. Jedyną różnicą jest to, że dispatch_syncpowrót następuje tylko po zakończeniu bloku, podczas gdy dispatch_asyncpowrót po dodaniu go do kolejki i może się nie zakończyć.
Uwaga: w przypadku pierwszego kodu nie zostanie wydrukowany 1324. Ponieważ printf("3")jest wysyłany poprintf("2") wykonaniu. Zadanie można wykonać dopiero po wysłaniu.
Czas wykonania zadań niczego nie zmienia. Ten kod jest zawsze drukowany12
moje pytanie brzmi: dlaczego nie zrobiliśmy tego w normalny sposób? printf("1");printf("2") ;printf("3") ;printf("4")- w porównaniu zdispatch_sync
androniennn
@androniennn jako drugi przykład? ponieważ dispatch_sync(_serialQueue, ^{ /*change shared data*/ });w tym samym czasie może działać inny wątek .
Bryan Chen,
1
@ asma22 Bardzo przydatne jest udostępnianie bezpiecznego obiektu niebędącego wątkiem między wieloma wątkami / kolejkami wysyłkowymi. Jeśli uzyskujesz dostęp do obiektu tylko w kolejce szeregowej, wiesz, że uzyskujesz do niego bezpieczny dostęp.
Bryan Chen
1
Mam na myśli seryjną egzekucję . Z punktu widzenia, że wszystkie zadania są wykonywane seryjnie w odniesieniu do innych zadań w tej samej kolejce. Oczywiście może to być równoczesne w odniesieniu do innych kolejek. Głównym celem GCD jest to, że zadania mogą być wysyłane i wykonywane jednocześnie.
Bryan Chen
19
Różnica między dispatch_synci dispatch_asyncjest prosta.
W obu twoich przykładach TASK 1zawsze będzie wykonywany wcześniej, TASK 2ponieważ został wysłany przed nim.
W tym dispatch_syncprzykładzie nie wyślesz jednak, TASK 2dopóki TASK 1nie zostanie wysłany i wykonany . Nazywa się to „blokowaniem” . Twój kod czeka (lub „blokuje”), aż zadanie zostanie wykonane.
W tym dispatch_asyncprzykładzie Twój kod nie będzie czekał na zakończenie wykonywania. Oba bloki zostaną wysłane (i umieszczone w kolejce) do kolejki, a reszta kodu będzie kontynuowana w tym wątku. Następnie w pewnym momencie w przyszłości (w zależności od tego, co jeszcze zostało wysłane do Twojej kolejki),Task 1 wykona, a następnie Task 2wykona.
Myślę, że źle zamówiłeś. pierwszy przykład to asyncwersja nieblokująca
Bryan Chen,
Zmieniłem twoją odpowiedź na to, co myślę, że miałeś na myśli . Jeśli tak nie jest, zmień to i wyjaśnij.
JRG-Developer,
1
Co się stanie, jeśli wywołasz dispatch_sync, a następnie dispatch_async w tej samej kolejce? (i odwrotnie)
0xSina
1
W kolejce szeregowej oba zadania są nadal wykonywane jedno po drugim. W pierwszym przypadku dzwoniący czeka na zakończenie pierwszego bloku, ale nie czeka na drugi blok. W drugim przypadku dzwoniący nie czeka na zakończenie pierwszego bloku, ale czeka na drugi blok. Ale ponieważ kolejka wykonuje bloki po kolei, wywołujący faktycznie czeka na zakończenie obu.
gnasher729
1
Blok mógłby również wykonać procedurę dispatch_async na swojej własnej kolejce (dodając kolejne bloki, które zostaną wykonane później); dispatch_sync we własnej kolejce szeregowej lub kolejce głównej byłby zakleszczony. W tej sytuacji dzwoniący będzie czekał na zakończenie oryginalnego bloku, ale nie na inne bloki. Pamiętaj tylko: dispatch_sync umieszcza blok na końcu kolejki, kolejka wykonuje kod do zakończenia tego bloku, a następnie powraca dispatch_sync. dispatch_async po prostu dodaje blok na końcu kolejki.
gnasher729
5
To wszystko jest związane z główną kolejką. Istnieją 4 permutacje.
i) Kolejka szeregowa, wysyłka asynchroniczna: tutaj zadania będą wykonywane jedno po drugim, ale główny wątek (wpływ na interfejs użytkownika) nie będzie czekał na powrót
ii) Kolejka szeregowa, synchronizacja wysyłki: Tutaj zadania będą wykonywane jedno po drugim, ale główny wątek (wpływ na interfejs użytkownika) pokaże opóźnienie
iii) Kolejka współbieżna, wysyłka asynchroniczna: tutaj zadania będą wykonywane równolegle, a główny wątek (wpływ na interfejs użytkownika) nie będzie czekał na powrót i będzie działał płynnie.
iv) Równoczesna kolejka, synchronizacja wysyłek: tutaj zadania będą wykonywane równolegle, ale główny wątek (wpływ na interfejs użytkownika) pokaże opóźnienie
Wybór kolejki współbieżnej lub szeregowej zależy od tego, czy potrzebujesz danych wyjściowych z poprzedniego zadania dla następnego. Jeśli polegasz na poprzednim zadaniu, zastosuj kolejkę szeregową, w przeciwnym razie weź kolejkę współbieżną.
I na koniec, jest to sposób na powrót do głównego wątku, gdy skończymy z naszą działalnością:
printf("1");printf("2") ;printf("3") ;printf("4")
- w porównaniu zdispatch_sync
dispatch_sync(_serialQueue, ^{ /*change shared data*/ });
w tym samym czasie może działać inny wątek .Różnica między
dispatch_sync
idispatch_async
jest prosta.W obu twoich przykładach
TASK 1
zawsze będzie wykonywany wcześniej,TASK 2
ponieważ został wysłany przed nim.W tym
dispatch_sync
przykładzie nie wyślesz jednak,TASK 2
dopókiTASK 1
nie zostanie wysłany i wykonany . Nazywa się to „blokowaniem” . Twój kod czeka (lub „blokuje”), aż zadanie zostanie wykonane.W tym
dispatch_async
przykładzie Twój kod nie będzie czekał na zakończenie wykonywania. Oba bloki zostaną wysłane (i umieszczone w kolejce) do kolejki, a reszta kodu będzie kontynuowana w tym wątku. Następnie w pewnym momencie w przyszłości (w zależności od tego, co jeszcze zostało wysłane do Twojej kolejki),Task 1
wykona, a następnieTask 2
wykona.źródło
async
wersja nieblokującaTo wszystko jest związane z główną kolejką. Istnieją 4 permutacje.
i) Kolejka szeregowa, wysyłka asynchroniczna: tutaj zadania będą wykonywane jedno po drugim, ale główny wątek (wpływ na interfejs użytkownika) nie będzie czekał na powrót
ii) Kolejka szeregowa, synchronizacja wysyłki: Tutaj zadania będą wykonywane jedno po drugim, ale główny wątek (wpływ na interfejs użytkownika) pokaże opóźnienie
iii) Kolejka współbieżna, wysyłka asynchroniczna: tutaj zadania będą wykonywane równolegle, a główny wątek (wpływ na interfejs użytkownika) nie będzie czekał na powrót i będzie działał płynnie.
iv) Równoczesna kolejka, synchronizacja wysyłek: tutaj zadania będą wykonywane równolegle, ale główny wątek (wpływ na interfejs użytkownika) pokaże opóźnienie
Wybór kolejki współbieżnej lub szeregowej zależy od tego, czy potrzebujesz danych wyjściowych z poprzedniego zadania dla następnego. Jeśli polegasz na poprzednim zadaniu, zastosuj kolejkę szeregową, w przeciwnym razie weź kolejkę współbieżną.
I na koniec, jest to sposób na powrót do głównego wątku, gdy skończymy z naszą działalnością:
źródło