Синхронизация отправки в текущей очереди

Я знаю, что вы можете найти этот странный вопрос, но я просто изучаю GCD, и я хочу полностью понять все его аспекты. Итак, вот оно:

Есть ли какая-либо причина для отправки задачи SYNC в CURRENT QUEUE?

Например:

    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(...);
    dispatch_async(concurrentQueue, ^{
       //this is work task 0

       //first do something here, then suddenly:

       dispatch_sync(concurrentQueue, ^{
               //work task 1
       });

       //continue work task 0
    });

Я понимаю одно: если вместо concurrentQueue я использую последовательную очередь, тогда я получаю тупик в этой последовательной очереди, потому что work task 1 не может запускаться до завершения work task 0 (из-за последовательной очереди, которая гарантирует порядок выполнения), и в то же время work task 0 не может продолжить свое выполнение, потому что ожидает возвращения функции SYNC (пожалуйста, исправьте меня, если я ошибаюсь, что сделало бы меня общий нуб).

Итак, вернемся к оригинальной идее, есть ли какая-либо разница между кодом выше и тем же кодом, где вместо вызова функции dispatch_sync я просто пишу work task 1 код напрямую?

Ответ 1

Нет. Я не могу придумать причину когда-либо dispatch_sync в той же параллельной очереди, в которой вы уже находитесь. Если вы это сделаете, GCD сразу вызовет ваш блок, в строке, в том же потоке, как если бы вы вызвали его напрямую. (Я проверил.) И, как вы указали, выполнение этого в последовательной очереди приведет к блокировке вас.

Ответ 2

Предположим, что эта очередь для всех примеров:

dispatch_queue_t queue = dispatch_queue_create ( "com.somecompany.queue", ноль);

Ситуация 1 - ОК

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 1");
    });
});

Ситуация 2 - Не в порядке! Тупик!

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 2"); // NOT REACHED!  DEADLOCK!
    });
});

Ситуация 3 - Не в порядке! Тупик!

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 3"); // NOT REACHED!  DEADLOCK!
    });
});

Ситуация 4 - ОК

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 4");
    });
});

В принципе dispatch_sync не любит быть внутри.

Только dispatch_asyncs могут войти внутрь.