Подтвердить что ты не робот

IOS GCD: Разница между любой глобальной очередью и приоритетом фона (DISPATCH_QUEUE_PRIORITY_BACKGROUND)?

Я читаю Concurrency Руководство по программированию, и все меня пугает.

Я вижу много кода, вызывающего следующее для любой фоновой задачи:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

Теперь, что я имею в виду под "фоном", это популярное значение:

Что-то, что выполняется в любом другом месте, кроме основного (UI) потока

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

Мой вопрос: почему существует DISPATCH_QUEUE_PRIORITY_BACKGROUND? В последнее время я также вижу много задач async, используя DISPATCH_QUEUE_PRIORITY_BACKGROUND специально для выполнения фоновых задач.

Не возвращаются ли очереди с DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_LOW или DISPATCH_QUEUE_PRIORITY_HIGH очень сильно от основного потока, если они возвращаются с помощью dispatch_get_global_queue?

Разве это не фоновые очереди? Какая конкретная цель возвращает очередь с помощью DISPATCH_QUEUE_PRIORITY_BACKGROUND? Я уже ссылался на это, но это не разъясняет многое, кроме популярного значения, упомянутого выше.

Я уверен, что меня довольно путают со словами - фоновые и фоновые очереди. Если кто-то может объяснить (лучше, графически) - будет большой помощью.

4b9b3361

Ответ 1

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

В очень редких случаях у вас может быть задача, которая занимает много времени, но это нормально ждать. Таким образом, вы придаете ему приоритет BACKGROUND. Если в приоритете NORMAL есть какая-либо работа, эта работа будет выполнена в первую очередь, и только тогда, когда запасной процессор ничего не сделает, задача BACKGROUND будет выполнена. И есть очередь с высоким приоритетом; задачи в этой очереди будут выполнены в первую очередь; вы сделали бы это, если одна конкретная задача должна быть завершена как можно быстрее, даже если это означает, что другие задачи задерживаются.

С точки зрения вашей логики программирования все три очереди идентичны. Это просто влияет на задачи, которые ОС сначала пытается завершить, и которые это не волнует.

Ответ 2

Это объясняется довольно хорошо в заголовке dispatch/queue.h:

DISPATCH_QUEUE_PRIORITY_HIGH Элементы, отправленные в очередь, будут выполняться с высоким приоритетом, то есть очередь будет запланирована для выполнения до любой очереди по умолчанию или очереди с низким приоритетом.

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

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

DISPATCH_QUEUE_PRIORITY_BACKGROUND Элементы, отправленные в очередь, будут выполняться с приоритетом фона, то есть в очереди будет запланировано на выполнение после того, как все очереди с более высоким приоритетом будут и система будет запускать элементы в этой очереди в потоке с помощью (2) (то есть дисковый ввод-вывод дросселируется, и приоритет планирования потока установлен на минимальное значение).

И имейте в виду, что это глобальная очередь. Другие вещи, такие как системные рамки, могут планировать его. Очень легко голодать полосы приоритета - если запланировано множество запланированных задач DISPATCH_QUEUE_PRIORITY_HIGH, задачам с приоритетом по умолчанию может потребоваться некоторое время перед выполнением. И задачи в DISPATCH_QUEUE_PRIORITY_BACKGROUND, возможно, придется ждать очень долго, так как все остальные приоритеты над ними должны быть пустыми.

Многие разработчики злоупотребляют глобальной параллельной очередью. Они хотят выполнить блок, нуждаются в очереди и просто использовать это по приоритету по умолчанию. Такая практика может привести к очень сложному устранению ошибок. Глобальная параллельная очередь является общим ресурсом и к ней следует относиться с осторожностью. В большинстве случаев имеет смысл создавать приватную очередь.

Параллельная очередь не является асинхронной, она параллельна. Синхронные задачи все еще могут быть запланированы, и они все равно будут выполняться синхронно. Одновременные очереди, такие как последовательные очереди, деактивируются в порядке FIFO. Они выполняют блоки одновременно, в отличие от последовательных очередей. Параллельные и асинхронные - это не одно и то же.

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

Блоки, отправленные в эти очереди отправки, вызываются в пуле потоков, полностью управляемых системой. Никакой гарантии в отношении на который будет ссылаться блок; однако гарантируется, что только один блок, отправленный в очередь отправки FIFO, будет вызываться одновременно.

GCD не дает никаких гарантий относительно того, какой поток будет использоваться для выполнения блока в параллельной очереди. Если вы используете основную очередь, блок будет выполняться последовательно по основному потоку. Одновременная очередь может использовать любой поток, и в качестве оптимизации предпочтительнее использовать существующие потоки. Он будет создавать только новый поток, если потоки не будут использоваться повторно. И на самом деле основной поток часто является первым выбором (если основной поток доступен для работы), потому что он "теплый".

Повторить: С помощью Grand Central Dispatch вы можете быть уверены, что задача будет выполнена в основном потоке (путем отправки в основную очередь). Вы не можете быть уверены, что задача не будет выполняться в основном потоке.