web-dev-qa-db-fra.com

Quelle est la différence entre dispatch_get_global_queue et dispatch_queue_create?

J'écris un programme iOS modérément complexe qui doit avoir plusieurs threads pour certaines de ses opérations plus longues (analyse, connexions au réseau ... etc.). Cependant, je suis confus quant à la différence entre dispatch_get_global_queue et dispatch_queue_create.

Laquelle dois-je utiliser et pourriez-vous me donner une explication simple de la différence en général? Merci.

42
Nosrettap

Comme le décrit documentation , une file d'attente globale est bonne pour les tâches simultanées (c'est-à-dire que vous allez distribuer diverses tâches de manière asynchrone et vous êtes parfaitement satisfait si elles s'exécutent simultanément) et si vous ne voulez pas rencontrez les frais généraux théoriques de la création et de la destruction de votre propre file d'attente.

La création de votre propre file d'attente est très utile si vous avez besoin d'une file d'attente série (c'est-à-dire que vous avez besoin que les blocs envoyés soient exécutés un par un). Cela peut être utile dans de nombreux scénarios, par exemple lorsque chaque tâche dépend de la précédente ou lors de la coordination de l'interaction avec une ressource partagée à partir de plusieurs threads.

Moins courant, mais vous souhaiterez également créer votre propre file d'attente si vous devez utiliser obstacles en conjonction avec une file d'attente simultanée. Dans ce scénario, créez une file d'attente simultanée (c'est-à-dire dispatch_queue_create avec le DISPATCH_QUEUE_CONCURRENT option) et utiliser les barrières conjointement avec cette file d'attente. Vous ne devez jamais utiliser de barrières sur les files d'attente globales.

Mon conseil général est que si vous avez besoin d'une file d'attente en série (ou si vous devez utiliser des barrières), créez une file d'attente. Si vous ne le faites pas, allez-y et utilisez la file d'attente globale et évitez la surcharge de création de la vôtre.


Si vous souhaitez une file d'attente simultanée, mais souhaitez contrôler le nombre d'opérations pouvant s'exécuter simultanément, vous pouvez également envisager d'utiliser NSOperationQueue qui possède une propriété maxConcurrentOperationCount. Cela peut être utile lors des opérations réseau et vous ne voulez pas que trop de demandes simultanées soient soumises à votre serveur.

71
Rob

Je viens de poster dans une réponse différente, mais voici quelque chose que j'ai écrit il y a longtemps:

La meilleure façon de conceptualiser les files d'attente est de réaliser d'abord qu'au niveau très bas, il n'y a que deux types de files d'attente: série et simultanée.

Les files d'attente série sont monogames, mais non validées. Si vous donnez un tas de tâches à chaque file d'attente série, il les exécutera une à la fois, en utilisant un seul thread à la fois. L'aspect non engagé est que les files d'attente série peuvent basculer vers un autre thread entre tâches. Les files d'attente série attendent toujours la fin d'une tâche avant de passer à la suivante. Ainsi, les tâches sont exécutées dans l'ordre FIFO. Vous pouvez créer autant de files d'attente série que nécessaire avec dispatch_queue_create.

La file d'attente principale est une file d'attente série spéciale. Contrairement aux autres files d'attente série, qui ne sont pas validées, en ce qu'elles "datent" de nombreux threads mais un seul à la fois, la file d'attente principale est "mariée" au thread principal et toutes les tâches y sont exécutées. Les travaux sur la file d'attente principale doivent se comporter correctement avec la boucle d'exécution afin que les petites opérations ne bloquent pas l'interface utilisateur et les autres bits importants. Comme toutes les files d'attente série, les tâches sont exécutées dans l'ordre FIFO.

Si les files d'attente série sont monogames, alors les files d'attente simultanées sont promiscues. Ils soumettront des tâches à n'importe quel thread disponible ou même créeront de nouveaux threads en fonction de la charge du système. Ils peuvent effectuer plusieurs tâches simultanément sur différents threads. Il est important que les tâches soumises à la file d'attente globale soient thread-safe et minimisent les effets secondaires. Les tâches sont soumises pour exécution dans l'ordre FIFO, mais l'ordre d'achèvement n'est pas garanti. À ce jour, il n'y a que trois files d'attente simultanées et vous ne pouvez pas les créer, vous pouvez uniquement les récupérer avec dispatch_get_global_queue.

modifier: article de blog développant cette réponse: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html

40
amattn

L'un renvoie la file d'attente globale existante, l'autre en crée une nouvelle. Au lieu d'utiliser GCD, j'envisagerais d'utiliser NSOperation et la file d'attente d'opérations. Vous pouvez trouver plus d'informations à ce sujet dans ce guide. Généralement, vous voulez que les opérations s'exécutent simultanément, vous voulez créer votre propre file d'attente et y placer vos opérations.

0
Max Yankov