Какая разница между "глобальной очередью" и "главной очередью" в GCD? - программирование
Подтвердить что ты не робот

Какая разница между "глобальной очередью" и "главной очередью" в GCD?

Среди других способов есть два способа получить очереди в GCD:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_get_main_queue();

Если я не совсем ошибаюсь, "основная очередь" выполняется в основном потоке и хороша для блоков "обратного вызова", которые выполняют работу пользовательского интерфейса.

Означает ли это, что "глобальная очередь" - это ту, которая работает на фоновом потоке?

4b9b3361

Ответ 1

Основная очередь действительно работает на основном потоке, как вы говорите.

Глобальные очереди - это параллельные очереди и с главной страницы для dispatch_get_global_queue:

В отличие от основной очереди или очередей, выделенных dispatch_queue_create(), глобальные параллельные очереди планировать блоки, как только потоки станут доступными (порядок завершения "не-FIFO" ). Глобальный параллельный      очереди представляют собой три полосы приоритета:

       •   DISPATCH_QUEUE_PRIORITY_HIGH
       •   DISPATCH_QUEUE_PRIORITY_DEFAULT
       •   DISPATCH_QUEUE_PRIORITY_LOW

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

Таким образом, они представляют собой очереди, которые работают по фоновым потокам по мере их появления. Они "не-FIFO", поэтому заказ не гарантируется.

Ответ 2

5 очередей (4 фона, 1 основной) имеют разные приоритеты потоков (-[NSThread threadPriority]):

                            -main- : 0.758065
      DISPATCH_QUEUE_PRIORITY_HIGH : 0.532258
   DISPATCH_QUEUE_PRIORITY_DEFAULT : 0.500000
       DISPATCH_QUEUE_PRIORITY_LOW : 0.467742
DISPATCH_QUEUE_PRIORITY_BACKGROUND : 0.000000

(протестировано на iPod 4-го поколения и симуляторе на MacBook Pro)

Ответ 3

Да. Вы можете запустить такой код на устройстве, чтобы проверить его:

dispatch_async(
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"Block 1a");
            NSAssert(![NSThread isMainThread], @"Wrong thread!");
            NSLog(@"Block 1b");
        });
dispatch_async(
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@"Block 2a");
                    NSAssert([NSThread isMainThread], @"Wrong thread!");
                    NSLog(@"Block 2b");
                });
        });

Ответ 4

Последовательные очереди и параллельные очереди

Очереди могут быть serial или concurrent.

Serial или последовательно: когда iOS закрывает верхнюю часть очереди и работает до конца, затем извлекает другой элемент очереди и т.д.

Concurrent или многопоточный, когда система вытягивает замыкание в верхней части очереди и запускает его выполнение в определенном потоке.

enter image description here

Синхронный и асинхронный

С помощью GCD вы можете отправить задачу либо synchronously, либо asynchronously.

Функция synchronous возвращает управление вызывающей стороне после выполнения задачи. Он блокирует очередь и ожидает завершения задачи. Вы можете запланировать единицу работы синхронно, позвонив в DispatchQueue.sync(execute:).

enter image description here

Функция asynchronous немедленно возвращается, приказывая запустить задачу, но не дожидаясь ее завершения. Таким образом, асинхронная функция не блокирует текущий поток выполнения от перехода к следующей функции. Вы можете запланировать единицу работы асинхронно, вызвав DispatchQueue.async(execute:).

enter image description here

Глобальные очереди отправки

GCD предоставляет три основных типа очередей:

Main queue: работает на main thread и является serial queue. Это обычный выбор для обновления пользовательского интерфейса после завершения работы в задаче в параллельной очереди.

Global queues: concurrent queues, которые являются общими для всей системы. Это обычный выбор для выполнения работы без пользовательского интерфейса в фоновом режиме. Существует четыре таких очереди с разными приоритетами: high, default, low и background. Фоновая очередь с приоритетами имеет самый низкий приоритет и регулируется в любой операции ввода-вывода, чтобы минимизировать негативное влияние на систему. При настройке глобальных параллельных очередей приоритет не указывается напрямую. Вместо этого вы указываете свойство класса Quality of Service (QoS):

  • User-interactive - Это представляет задачи, которые должны быть выполнены немедленно, чтобы обеспечить приятный пользовательский опыт. Это должно выполняться в главном потоке.

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

  • Utility - представляет долговременные задачи, обычно с видимым пользователем индикатором прогресса. Используйте его для вычислений, ввода/вывода, работы в сети, непрерывной подачи данных и подобных задач. Этот класс предназначен для энергосбережения.

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

Custom queues: запросы в этих очередях фактически попадают в одну из глобальных очередей. Созданные вами очереди, которые могут быть serial or concurrent

Общий асинхронный против синхронного

Подробнее здесь, здесь, здесь

Ответ 5

Глобальная очередь отправки:

  • Задачи в параллельной очереди выполняются одновременно [фоновые потоки]
  • Задачи все еще запущены в том порядке, в котором они были добавлены в очередь

Основная очередь отправки:

  • Доступная последовательная очередь, выполняющая задачи на основном приложении нить.
  • Обычно он вызывается из фоновой очереди, когда некоторые завершена фоновая обработка, и пользовательский интерфейс должен обновляться.