Какая разница между "глобальной очередью" и "главной очередью" в GCD?
Среди других способов есть два способа получить очереди в GCD
:
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_get_main_queue();
Если я не совсем ошибаюсь, "основная очередь" выполняется в основном потоке и хороша для блоков "обратного вызова", которые выполняют работу пользовательского интерфейса.
Означает ли это, что "глобальная очередь" - это ту, которая работает на фоновом потоке?
Ответы
Ответ 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
Глобальная очередь отправки:
- Задачи в параллельной очереди выполняются одновременно [фоновые потоки]
- Задачи все еще запущены в том порядке, в котором они были добавлены в очередь
Основная очередь отправки:
- Доступная последовательная очередь, выполняющая задачи на основном приложении
нить.
- Обычно он вызывается из фоновой очереди, когда некоторые
завершена фоновая обработка, и пользовательский интерфейс должен
обновляться.