La solution GCD Producer-Consumer d'Apple doc est erronée?

Dans la section Migration de Threads du guide de programmation de concurrency d'Apple, il y a
Modification des implémentations Producteur-Consommateur , qui prétend que l'implémentation typique de la variable d'état multi-étapes pthread mutex + peut être simplifiée en utilisant GCD.

Avec les files d'attente d'expédition, vous pouvez simplifier les implémentations du producteur et du consommateur en un seul appel:

dispatch_async(queue, ^{ // Process a work item. }); 

Lorsque votre producteur a du travail à faire, tout ce qu'il a à faire est d'append ce travail à une queue et laisser la queue traiter l'élément.

Le problème du producteur-consommateur est également connu sous le nom de problème tampon-borné, mais ce qui précède ne fait aucune mention d'un tampon, de sa borne ou du consommateur, et encore less du producteur et du consommateur pour éviter les dépassements.

Comment cela peut-il être une solution valable?

Dans la solution décrite dans ce document Apple:

  1. Il n'y a pas de tampon car aucun tampon n'est nécessaire;
  2. La charge du système est la limite;
  3. Les consommateurs sont des tâches.

Supposons que vous ayez plusieurs producteurs et consommateurs, que les producteurs placent datatables dans un tampon partagé et que les consommateurs lisent datatables de ce tampon partagé. Un sémaphore ou un moniteur est utilisé pour synchroniser l'access au tampon partagé, et la taille de la memory tampon est fixée de manière à limiter la quantité de données produites en fonction du taux de consommation, ce qui limite le producteur.

Sous Grand Central Dispatch, les consommateurs sont des tâches envoyées à une queue. Puisque les tâches sont des blocs Objective-C, un producteur n'a pas besoin d'un tampon pour indiquer au consommateur datatables qu'il doit traiter: Les blocs Objective-C capturent automatiquement les objects qu'ils referencent.

Par exemple:

 // Producer implementation while (…) { id dataProducedByTheProducer; // Produce data and place it in dataProducedByTheProducer dataProducedByTheProducer = …; // Dispatch a new consumer task dispatch_async(queue, ^{ // This task, which is an Objective-C block, is a consumer. // // Do something with dataProducedByTheProducer, which is // the data that would otherwise be placed in the shared // buffer of a traditional, semaphore-based producer-consumer // implementation. // // Note that an Objective-C block automatically keeps a // strong reference to any Objective-C object referenced // inside of it, and the block releases said object when // the block itself is released. NSSsortingng *s = [dataProducedByTheProducer …]; }); } 

Le producteur peut placer autant de tâches de consommation que de données qu'il peut produire. Cependant, cela ne signifie pas que GCD lancera les tâches du consommateur au même rythme. GCD utilise les informations du operating system pour contrôler la quantité de tâches exécutées en fonction de la charge du système en cours. Le producteur lui-même n'est pas limité, et dans la plupart des cas, cela n'est pas dû à l'équilibrage de charge insortingnsèque de GCD.

S'il y a un besoin réel d'étrangler le producteur, une solution consiste à avoir un maître qui enverrait n tâches de producteur et à chaque consommateur d'informer le maître (via une tâche dissortingbuée après que le consommateur a fini son travail) qu'il a fini, dans lequel Dans le cas contraire, le capitaine enverrait une autre tâche de producteur. Alternativement, le consommateur lui-même pourrait envoyer une tâche de producteur à la fin.

Répondre spécifiquement aux éléments que vous avez abordés:

Le problème producteur-consommateur est également connu sous le nom de problème tampon-borné, mais ce qui précède ne fait aucune mention d'un tampon

Un tampon partagé n'est pas nécessaire car les consommateurs sont des blocs Objective-C, qui capturent automatiquement datatables qu'ils referencent.

sa limite

GCD limite le nombre de tâches dissortingbuées en fonction de la charge système actuelle.

ou le consommateur

Les consommateurs sont les tâches envoyées aux files d'attente GCD.

encore less bloquer le producteur et le consommateur afin d'éviter les dépassements

Il n'y a pas besoin de bloquer car il n'y a pas de tampon partagé. Comme chaque consommateur est un bloc Objective-C capturant datatables produites via le mécanisme de capture de context de bloc Objective-C, il existe une relation un-à-un entre le consommateur et datatables.