Разница между dispatch async и dispatch sync в последовательной очереди?
Я создал последовательную очередь, как это:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
в чем разница между dispatch_async называли
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
и dispatch_sync называется так в этой последовательной очереди?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
Я понимаю, что, независимо от того, какой метод отправки используется,TASK 1 будет выполнен и завершен до TASK 2, верно?
3 ответов:
да. Использование последовательной очереди обеспечивает последовательное выполнение задач. Разница только в том, что
dispatch_syncвозвращается только после завершения блока, тогда какdispatch_asyncвозврат после добавления в очередь и может не закончиться.код
dispatch_async(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_async(_serialQueue, ^{ printf("3"); }); printf("4");он может печатать
2413или2143или1234но1всегда перед3код
dispatch_sync(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_sync(_serialQueue, ^{ printf("3"); }); printf("4");он всегда печатать
1234
Примечание: Для первый код, это не print
1324. Потому чтоprintf("3")отправлено послеprintf("2")выполняется. И задача может быть выполнена только после он будет отправлен.
время выполнения задач ничего не меняет. Этот код всегда печатает
12dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); }); dispatch_async(_serialQueue, ^{ printf("2"); });что может случиться
- поток 1: dispatch_async трудоемкая задача (задача 1) для последовательного очередь
- поток 2: начните выполнение задачи 1
- поток 1: dispatch_async другая задача (задача 2) в последовательную очередь
- поток 2: Задача 1 завершена. начните выполнение задачи 2
- поток 2: Задача 2 завершена.
и
12
разницу между
dispatch_syncиdispatch_asyncпрост.в обоих ваших примерах,
TASK 1всегда будет выполняться передTASK 2потому что он был послан перед ним.на
dispatch_syncпример, однако, вы не будете отправлятьTASK 2доTASK 1было передано и исполнено. Это называется "блокирование". Ваш код ждет (или "блокирует"), пока задача не будет выполнена.на
dispatch_asyncпримеру, ваш код не будет ждать завершения выполнения. Оба блока будут отправлены (и поставлены в очередь) в очередь, а остальная часть вашего кода будет продолжать выполняться в этом потоке. Затем в какой-то момент в будущем (в зависимости от того, что еще было отправлено в вашу очередь),Task 1выполнит и тогдаTask 2будет выполнять.
все это связано с основной очереди. Есть 4 перестановки.
i) последовательная очередь, отправка асинхронно : здесь задачи будут выполняться одна за другой, но основной поток(эффект на UI) не будет ждать возврата
ii) последовательная очередь, синхронизация отправки: здесь задачи будут выполняться одна за другой, но основной поток(эффект на UI) будет показывать ЛАГ
iii) параллельная очередь, отправка асинхронно : здесь задачи будут выполняться параллельно и основной поток (эффект на UI) не будет ждать возврата и будет гладким.
iv) параллельная очередь, синхронизация отправки : здесь задачи будут выполняться параллельно, но основной поток (эффект на UI) будет показывать ЛАГ
выбор параллельной или последовательной очереди зависит от того, требуется ли вывод из предыдущей задачи для следующей. Если вы зависите от предыдущей задачи, примите последовательную очередь, иначе возьмите параллельную очередь.
и, наконец, это способ проникать в основной поток, когда мы закончим с нашим бизнесом:
DispatchQueue.main.async { // Do something here }
Comments