Разница между 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, верно?

704   3  

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") выполняется. И задача может быть выполнена только после он будет отправлен.


время выполнения задач ничего не меняет. Этот код всегда печатает 12

dispatch_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

    Ничего не найдено.