Да. Использование последовательной очереди обеспечивает последовательное выполнение задач. Единственное отличие состоит в том, что dispatch_syncвозврат только после завершения блока, тогда как dispatch_asyncвозврат после того, как он добавлен в очередь и может не завершиться.
Примечание. Первый код не печатается 1324. Потому printf("3")что отправляется послеprintf("2") выполнения. И задача может быть выполнена только после отправки.
Время выполнения задач ничего не меняет. Этот код всегда печатается12
у меня вопрос: почему мы не сделали это как обычно? printf("1");printf("2") ;printf("3") ;printf("4")- по сравнению сdispatch_sync
androniennn
@androniennn для второго примера? потому что в то dispatch_sync(_serialQueue, ^{ /*change shared data*/ });же время может работать какой-то другой поток .
Брайан Чен
1
@ asma22 Очень полезно разделять небезопасный для потоков объект между несколькими потоками / очередями отправки. Если вы обращаетесь к объекту только в последовательной очереди, вы знаете, что обращаетесь к нему безопасно.
Брайан Чен
1
Я имею в виду серийную казнь . С точки зрения того, что все задачи выполняются последовательно по отношению к другим задачам в той же очереди. Конечно, это все еще может быть одновременным по отношению к другим очередям. Вся суть GCD в том, что задачи могут отправляться и выполняться одновременно.
Брайан Чен
19
Разница между dispatch_syncи dispatch_asyncпроста.
В обоих ваших примерах TASK 1всегда будет выполняться раньше, TASK 2потому что он был отправлен до него.
В этом dispatch_syncпримере, однако, вы не будете отправлять сообщения TASK 2до TASK 1тех пор, пока они не будут отправлены и выполнены . Это называется «блокировкой» . Ваш код ждет (или «блокируется»), пока задача не будет выполнена.
В этом dispatch_asyncпримере ваш код не будет ждать завершения выполнения. Оба блока будут отправлены (и поставлены в очередь) в очередь, а остальная часть вашего кода продолжит выполнение в этом потоке. Затем в какой-то момент в будущем (в зависимости от того, что еще было отправлено в вашу очередь), Task 1будет выполнено, а затем Task 2будет выполнено.
Я думаю, вы ошиблись в заказе. Первый пример - asyncэто неблокирующая версия
Брайан Чен
Я отредактировал ваш ответ так, как я думаю, вы имели в виду . Если это не так, пожалуйста, измените и поясните.
JRG-Developer
1
Что делать, если вы вызываете dispatch_sync, а затем dispatch_async в той же очереди? (и наоборот)
0xSina
1
В последовательной очереди обе задачи по-прежнему выполняются одна за другой. В первом случае вызывающий абонент ожидает завершения первого блока, но не ждет второго блока. Во втором случае вызывающий абонент не ждет завершения первого блока, а ждет второго блока. Но поскольку очередь выполняет блоки по порядку, вызывающий фактически ожидает завершения обоих.
gnasher729
1
Блок также может выполнять dispatch_async в своей собственной очереди (добавляя дополнительные блоки, которые будут выполнены позже); dispatch_sync в собственной последовательной очереди или основной очереди приведет к взаимной блокировке. В этой ситуации вызывающий будет ждать завершения исходного блока, но не других блоков. Просто помните: dispatch_sync помещает блок в конец очереди, очередь выполняет код до тех пор, пока этот блок не будет завершен, а затем возвращается dispatch_sync. dispatch_async просто добавляет блок в конец очереди.
gnasher729
6
Все это связано с основной очередью. Есть 4 перестановки.
i) Последовательная очередь, асинхронная отправка: здесь задачи будут выполняться одна за другой, но основной поток (влияние на пользовательский интерфейс) не будет ждать возврата
ii) Последовательная очередь, диспетчерская синхронизация: здесь задачи будут выполняться одна за другой, но основной поток (влияние на пользовательский интерфейс) будет показывать задержку
iii) Параллельная очередь, асинхронная отправка: здесь задачи будут выполняться параллельно, и основной поток (влияние на пользовательский интерфейс) не будет ждать возврата и будет плавным.
iv) Параллельная очередь, диспетчерская синхронизация: здесь задачи будут выполняться параллельно, но основной поток (влияние на пользовательский интерфейс) будет показывать задержку
Ваш выбор параллельной или последовательной очереди зависит от того, нужен ли вам вывод предыдущей задачи для следующей. Если вы зависите от предыдущей задачи, используйте последовательную очередь, иначе возьмите параллельную очередь.
И, наконец, это способ вернуться к основному потоку, когда мы закончим наши дела:
printf("1");printf("2") ;printf("3") ;printf("4")
- по сравнению сdispatch_sync
dispatch_sync(_serialQueue, ^{ /*change shared data*/ });
же время может работать какой-то другой поток .Разница между
dispatch_sync
иdispatch_async
проста.В обоих ваших примерах
TASK 1
всегда будет выполняться раньше,TASK 2
потому что он был отправлен до него.В этом
dispatch_sync
примере, однако, вы не будете отправлять сообщенияTASK 2
доTASK 1
тех пор, пока они не будут отправлены и выполнены . Это называется «блокировкой» . Ваш код ждет (или «блокируется»), пока задача не будет выполнена.В этом
dispatch_async
примере ваш код не будет ждать завершения выполнения. Оба блока будут отправлены (и поставлены в очередь) в очередь, а остальная часть вашего кода продолжит выполнение в этом потоке. Затем в какой-то момент в будущем (в зависимости от того, что еще было отправлено в вашу очередь),Task 1
будет выполнено, а затемTask 2
будет выполнено.источник
async
это неблокирующая версияВсе это связано с основной очередью. Есть 4 перестановки.
i) Последовательная очередь, асинхронная отправка: здесь задачи будут выполняться одна за другой, но основной поток (влияние на пользовательский интерфейс) не будет ждать возврата
ii) Последовательная очередь, диспетчерская синхронизация: здесь задачи будут выполняться одна за другой, но основной поток (влияние на пользовательский интерфейс) будет показывать задержку
iii) Параллельная очередь, асинхронная отправка: здесь задачи будут выполняться параллельно, и основной поток (влияние на пользовательский интерфейс) не будет ждать возврата и будет плавным.
iv) Параллельная очередь, диспетчерская синхронизация: здесь задачи будут выполняться параллельно, но основной поток (влияние на пользовательский интерфейс) будет показывать задержку
Ваш выбор параллельной или последовательной очереди зависит от того, нужен ли вам вывод предыдущей задачи для следующей. Если вы зависите от предыдущей задачи, используйте последовательную очередь, иначе возьмите параллельную очередь.
И, наконец, это способ вернуться к основному потоку, когда мы закончим наши дела:
источник