Синхронизация отправки в текущей очереди
Я знаю, что вы можете найти этот странный вопрос, но я просто изучаю 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 могут войти внутрь.