Что происходит внутри, когда dispatch_apply вызывается в dispatch_sync из той же параллельной очереди

#objective-c #c #multithreading #macos #grand-central-dispatch

#objective-c #c #многопоточность #macos #grand-central-dispatch

Вопрос:

Пример:

 dispatch_sync(someConcurrentQueue, ^(){
    dispatch_apply(5,someConcurrentQueue, ^(size_t i){
        // do some non-thread safe operation
     });
});
  

Я решил протестировать это и заметил, что не потокобезопасная операция выполняется, как ожидалось. Однако, когда я вызвал dispatch_sync, используя глобальную очередь, ситуация быстро ухудшилась.

Итак, мои вопросы: 1. Что происходит под капотом при подобном вызове? 2. Каждая ли итерация dispatch_apply предварительно запланирована в своем собственном потоке, а затем выполняется последовательно? 3. Если ответ на 2 положительный, приведет ли выполнение этого внутри бесконечного цикла к увеличению производительности? Причина в том, что операция может начать выполняться сразу после завершения последней вместо повторного цикла.

Ответ №1:

Это примерно то же самое, что:

 dispatch_sync(someConcurrentQueue, ^(){
    for (size_t i = 0; i < 5;   i){
        dispatch_async(someConcurrentQueue, ^(){
            // do some non-thread safe operation
        });
    }
});
  

Операции будут поставлены в очередь в той же очереди, в каком потоке будет выполняться код, зависит скорее от деталей реализации. Таким образом, если бы вы сделали это в бесконечном цикле, это выглядело бы примерно так:

  • синхронизация
  • асинхронность (0)
  • асинхронность (1)
  • асинхронность (2)
  • асинхронность (3)
  • асинхронность (4)
  • синхронизация

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