web-dev-qa-db-fra.com

Quelle est la différence entre la "file d'attente globale" et la "file d'attente principale" dans GCD?

Parmi d'autres façons, il existe deux façons d'obtenir des files d'attente dans GCD:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_get_main_queue();

Si je ne me trompe pas complètement, la "file d'attente principale" s'exécute sur le thread principal et convient aux blocs de "rappel" qui exécutent le travail de l'interface utilisateur.

Est-ce à dire qu'une "file d'attente globale" est celle qui s'exécute sur un thread d'arrière-plan?

55
Proud Member

La file d'attente principale fonctionne en effet sur le thread principal comme vous le dites.

Les files d'attente globales sont des files d'attente simultanées et à partir de la page principale de dispatch_get_global_queue:

Contrairement à la ou aux files d'attente principales allouées avec dispatch_queue_create (), les files d'attente simultanées globales planifient les blocs dès que les threads sont disponibles (ordre d'achèvement "non FIFO"). Les files d'attente simultanées globales représentent trois bandes prioritaires:

       •   DISPATCH_QUEUE_PRIORITY_HIGH
       •   DISPATCH_QUEUE_PRIORITY_DEFAULT
       •   DISPATCH_QUEUE_PRIORITY_LOW

Les blocs soumis à la file d'attente globale à priorité élevée seront appelés avant ceux soumis aux files d'attente globales par défaut ou à priorité faible. Les blocs soumis à la file d'attente globale à faible priorité ne seront invoqués que si aucun bloc n'est en attente sur les files d'attente par défaut ou à priorité élevée.

Ce sont donc des files d'attente qui s'exécutent sur des threads d'arrière-plan au fur et à mesure qu'elles deviennent disponibles. Ils sont "non FIFO", donc la commande n'est pas garantie.

76
mattjgalloway

Les 5 files d'attente (4 en arrière-plan, 1 principale) ont toutes des priorités de thread différentes ( -[NSThread threadPriority] ) aussi:

                            -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

(testé sur un iPod 4ème génération et le simulateur sur un MacBook Pro)

26
jjrscott

Oui. Vous pouvez exécuter du code comme celui-ci sur un appareil pour le tester:

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");
                });
        });

GCD propose trois principaux types de files d'attente:

  1. Main queue: S'exécute sur le thread principal et est une file d'attente série. Il s'agit d'un choix courant pour mettre à jour l'interface utilisateur après avoir terminé le travail d'une tâche dans une file d'attente simultanée.

  2. Global queues: Files d'attente simultanées partagées par l'ensemble du système. Il s'agit d'un choix courant pour effectuer un travail non-interface utilisateur en arrière-plan. Il existe quatre files d'attente de ce type avec des priorités différentes: high, default, low et background. La file d'attente de priorité en arrière-plan a la priorité la plus faible et est limitée dans toute activité d'E/S pour minimiser l'impact négatif sur le système. Lors de la configuration des files d'attente simultanées globales, vous ne spécifiez pas directement la priorité. À la place, vous spécifiez la propriété de classe Quality of Service (QoS):

    une. User-interactive - Ceci représente des tâches qui doivent être effectuées immédiatement afin de fournir une expérience utilisateur agréable. Cela devrait s'exécuter sur le thread principal .

    b. User-initiated - Le représente les tâches qui sont lancées à partir de l'interface utilisateur et peuvent être effectuées de manière asynchrone. Il doit être utilisé lorsque l'utilisateur attend des résultats immédiats et les tâches requises pour poursuivre l'interaction avec l'utilisateur.

    c. Utility - Cela représente des tâches de longue durée, généralement avec un indicateur de progression visible par l'utilisateur. Utilisez-le pour les calculs , E/S , mise en réseau , flux de données continus et tâches similaires. Cette classe est conçue pour être économe en énergie.

    ré. Background - Cela représente des tâches dont l'utilisateur n'a pas directement connaissance. Utilisez-le pour la prélecture, la maintenance et d'autres tâches qui ne nécessitent pas d'interaction de l'utilisateur et ne sont pas sensibles au facteur temps.

  3. Custom queues: Les demandes dans ces files d'attente se retrouvent en fait dans l'une des files d'attente globales. Les files d'attente que vous créez qui peuvent être

    une. Serial Queue - La seule file d'attente série globale est DispatchQueue.main, mais vous pouvez créer une file d'attente série privée.

    b. Concurrent Queue - Un bon choix lorsque vous souhaitez effectuer un travail de fond en série et le suivre.

Synchrone vs Asynchrone

En savoir plus ici , ici

4
yoAlex5

File d'attente de répartition globale:

  1. Les tâches dans la file d'attente simultanée s'exécutent simultanément [threads d'arrière-plan]
  2. Les tâches sont toujours démarrées dans l'ordre dans lequel elles ont été ajoutées à la file d'attente

File d'attente principale d'expédition:

  1. File d'attente série disponible qui exécute des tâches sur le thread principal de l'application.
  2. Il est généralement appelé à partir d'une file d'attente en arrière-plan lorsque le traitement en arrière-plan est terminé et que l'interface utilisateur doit être mise à jour.
4
Lyju I Edwinson