Вопрос по grand-central-dispatch, ios, multithreading, objective-c – В чем разница между dispatch_get_global_queue и dispatch_queue_create?

41

Я пишу довольно сложную программу для iOS, которая должна иметь несколько потоков для некоторых из ее более длительных операций (синтаксический анализ, подключение к сети ... и т. Д.). Однако я не совсем понимаю, какая разница междуdispatch_get_global_queue а такжеdispatch_queue_create.

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

Я выбрал неправильный ответ. Роберт Райан ответ более уместен Chandan Shetty SP

Ваш Ответ

3   ответа
70

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

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

Менее часто, но вы также захотите создать свою очередь, если вам нужно использоватьбарьеры в сочетании с параллельной очередью. В этом сценарии создайте параллельную очередь (т.е.dispatch_queue_create сDISPATCH_QUEUE_CONCURRENT вариант) и использовать барьеры вместе с этой очередью. Вы никогда не должны использовать барьеры в глобальных очередях.

Мой главный совет: если вам нужна последовательная очередь (или вам нужно использовать барьеры), то создайте очередь. Если вы этого не сделаете, продолжайте и используйте глобальную очередь и обходите издержки на создание своей собственной.

Если вы хотите параллельную очередь, но хотите контролировать, сколько операций может выполняться одновременно, вы также можете рассмотреть возможность использованияNSOperationQueue который имеетmaxConcurrentOperationCount имущество. Это может быть полезно при выполнении сетевых операций, и вы не хотите, чтобы на ваш сервер отправлялось слишком много одновременных запросов.

Обратите внимание, что в Lion теперь возможно получить параллельную очередь отdispatch_queue_create() мимоходомDISPATCH_QUEUE_CONCURRENT, Не указано (и, вероятно, не имеет значения), будет ли это просто возвращать одну из существующих глобальных очередей.
Небольшая заметка в ответ наmy own comment выше:DISPATCH_QUEUE_CONCURRENT фактически необходимо создать новую очередь, потому что можно использовать барьеры диспетчеризации в такой очереди, что недопустимо в глобальных очередях.
Я должен был добавить, «предположительно, что эта функциональность в конечном итоге появится в iOS».
За проголосовавшие правильно указали различия в терминах параллельных и последовательных очередей.
О разнице "mainQueue против anyOthercreatedSerialQueue". Хотя оба являются последовательными, mainQueue должен использоваться для задач, связанных с пользовательским интерфейсом, или, в основном, для чего-то важного, что должно быть немедленно возвращено (хотя я не могу придумать что-то хорошее сейчас). НоanyOthercreatedSerialQueue должен использоваться для специальной сериализации того, что вам, возможно, придется сделать в фоновом потоке, например, записи в массив, как вы уже представили в своем ответеhere
0

другой создает новую. Вместо того, чтобы использовать GCD, я бы рассмотрел использование NSOperation и Operation queue. Вы можете найти больше информации об этомв этом руководстве. Как правило, если вы хотите, чтобы операции выполнялись одновременно, вы хотите создать собственную очередь и поместить в нее свои операции.

Да, я говорю об очередях операций. Некоторое время назад я столкнулся с той же проблемой, и когда я создал собственную очередь операций без какой-либо дальнейшей настройки, добавленные в нее операции выполнялись одновременно друг с другом.
Просто чтобы уточнить, если вы создаете очередь отправки, это серийный номер. Если вы используете глобальную очередь отправки, она может быть параллельной (но не обязательно). Я предполагаю, что ваш советник по созданию очередей для параллелизма связан с очередями операций, а не с очередями отправки. (Я знаю, что вы это знаете, но я просто хотел убедиться, что читатели не запутались.)
40

но вот кое-что, что я написал довольно давно:

Лучший способ концептуализации очередей - это сначала понять, что на очень низком уровне существуют только два типа очередей: последовательная и параллельная.

Serial queues моногамны, но не совершены. Если вы дадите кучу задач каждой последовательной очереди, она будет запускать их по одной за раз, используя только один поток за раз. Неподтвержденный аспект заключается в том, что последовательные очереди могут переключаться на другой потокbetween задачи. Последовательные очереди всегда ждут завершения задачи, прежде чем перейти к следующей. Таким образом, задачи выполняются в порядке FIFO. Вы можете создать столько последовательных очередей, сколько вам нужноdispatch_queue_create.

main queue это специальная последовательная очередь. В отличие от других последовательных очередей, которые являются незафиксированными, в том, что они "датируются" много потоков, но только по одному, основная очередь «замужем» в основной поток, и все задачи выполняются на нем. Задания в главной очереди должны хорошо работать с циклом выполнения, чтобы небольшие операции не блокировали пользовательский интерфейс и другие важные биты. Как и все последовательные очереди, задачи выполняются в порядке FIFO.

Если последовательные очереди моногамны, тоconcurrent queues беспорядочные. Они будут отправлять задачи в любой доступный поток или даже создавать новые потоки в зависимости от загрузки системы. Они могут выполнять несколько задач одновременно в разных потоках. Важно, чтобы задачи, отправляемые в глобальную очередь, были поточно-ориентированными и сводили к минимуму побочные эффекты. Задания передаются на выполнение в порядке FIFO, но порядок выполнения не гарантируется. На момент написания этой статьи существует только три одновременных очереди, и вы не можете их создать, вы можете только получить их сdispatch_get_global_queue.

редактировать: сообщение в блоге, расширяющее этот ответ:http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html

Лучший. Ответ. Когда-либо.
Ссылка на запись в блоге не работает.
и неправильно ... Из моего опыта этот ответ не точный. Пользовательская очередь может быть создана (и функционировать) как параллельная очередь. @PaulRobinson
Кажется, все еще работает для меня. Я недавно обновил движки блогов, поэтому здесь есть новый канонический адрес:amattn.com/p/…
Из документации dispatch_queue_create Apple: в OS X v10.7 и новее или iOS 4.3 и новее укажите DISPATCH_QUEUE_SERIAL (или NULL), чтобы создать последовательную очередь, или DISPATCH_QUEUE_CONCURRENT, чтобы создать параллельную очередь. В более ранних версиях вы должны указать NULL для этого параметра.

Похожие вопросы