dispatch_async и dispatch_sync с использованием последовательных очередей в Grand Central Dispatch - PullRequest
23 голосов
/ 17 февраля 2011

Хорошо, я люблю Grand Central Dispatch и после того, как использую его с относительным успехом, но это то, что я не до конца понимаю.

Предположим, я создал свою собственную последовательную очередь, используя

dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("myQueue", NULL);

После этого я делаю это:

dispatch_async(myQueue, ^{
  [self doStuff1];
});

// and a few lines later...

dispatch_sync(myQueue, ^{
  [self doStuff2];
});

Первая отправка - асинхронная.Итак, это будет сделано одновременно, верно?Как это может быть, если myQueue является последовательным?Как последовательная очередь может работать параллельно или, если хотите, не в порядке?

спасибо

Ответы [ 3 ]

57 голосов
/ 17 февраля 2011

dispatch_async() означает, что блок поставлен в очередь, а dispatch_async() возвращается к постановке в очередь другой задачи / блока (возможно) до выполнения блока.

При dispatch_sync() блок ставится в очередь ифункция не будет продолжать ставить в очередь другую задачу / блок , пока не будет выполнен блок.

Блоки по-прежнему выполняются последовательно.Вы можете выполнить 100 dispatch_async() вызовов, каждый с блоком, который спит в течение 100 секунд, и это будет очень быстро.Затем выполните вызов dispatch_sync() в той же последовательной очереди, и dispatch_sync() вернется через ~ 10 000 секунд.

Проще говоря:

dispatch_async(serialQ, block1);
dispatch_async(serialQ, block2);
dispatch_sync(serialQ, block3);

block1 будет выполнено до block2, что будет выполнено до block3.Это порядок, гарантированный последовательной очередью.

Однако вызовы dispatch_async() могут вернуть до того, как начнет выполняться любой из блоков.dispatch_sync() будет не возвращаться до того, как будут выполнены все три блока!

4 голосов
/ 28 апреля 2016

Ни dispatch_async, ни dispatch_sync не изменяют способ, которым блок ставится в очередь.Если очередь последовательная, блоки будут выполняться последовательным образом, если очередь параллельная, одновременно.

Важное различие между ними состоит в том, что dispatch_sync ставит в очередь блок и ожидает на очередитекущий поток выполнения до тех пор, пока этот блок не будет выполнен и dispatch_async просто ставит блок в очередь и продолжает выполнение последующих инструкций.

1 голос
/ 18 декабря 2018

Последовательная очередь может запускать только одну задачу за раз, независимо от синхронизации или асинхронности.Последовательные очереди выделяются только одному потоку.Это будет легче понять, используя приведенный ниже пример -

Предположим, есть 2 очереди A и B, выполняющие задачи T1 и T2 соответственно и T1 выполняется асинхронно.Если управление переходит от A к B и B выполняет синхронно T2, то до тех пор, пока T2 (блок кода в блоке dispatch_sync) не завершит выполнение, T1 будет заблокирован.Когда T2 завершится, T1 возобновит свое выполнение.

...