8
votes

tampon à anneau sans inversion prioritaire

J'ai un processus hautement prioritaire qui doit adopter des données à un processus à faible priorité. J'ai écrit un tampon de bague de base pour gérer le passage des données: xxx

Voici le problème. Supposons que le processus de faible priorité ait un oracle qui lui indique exactement la quantité de données à lire, de sorte que compte () ne soit jamais appelé. Ensuite (sauf si je manque quelque chose), il n'y a pas de problèmes de concurrence. Cependant, dès que le fil à faible priorité doit appeler compter () (le thread de haute priorité pourrait vouloir l'appeler aussi pour vérifier si le tampon est trop complet) Il y a la possibilité que le maths in comptez () ou la mise à jour à la fin n'est pas atomique, introduisant un bug.

Je pourrais mettre un mutex autour des accès au début et à la fin, mais cela causerait une inversion prioritaire si le fil de haute priorité a Attendre la serrure acquise par le fil à faible priorité.

Je pourrais peut-être travailler quelque chose à l'aide d'opérations atomiques, mais je ne suis pas au courant d'une belle bibliothèque multiplate-forme qui les fournisse.

Y a-t-il une conception tampon standard qui évite ces problèmes?


3 commentaires

Avez-vous des contraintes sur les plates-formes utilisées?


@Peter Supposons X86 (où EIRC 32 bits écrit aux adresses alignées sont atomiques) bien que le plus portable mieux.


Voici une file d'attente qui fonctionne principalement logiciel .Intel.com / FR-US / Articles / ...


3 Réponses :


4
votes

Ce que vous avez devrait être correct, tant que vous adhérez à ces directives:

  • Un seul thread peut faire des écrires.
  • Un seul thread peut faire des lectures.
  • mises à jour et accès à Démarrer et fin sont atomiques. Cela pourrait être automatique, par exemple Microsoft States:

    simple lit et écrit à Les variables 32 bits correctement alignées sont Opérations atomiques. En d'autres termes, vous ne finira pas avec une seule partie de la variable mise à jour; Tous les bits sont mis à jour sous une mode atomique.

    • Vous permettez au fait que comptent pourrait être obsolète, même si vous obtenez la valeur. Dans le fil de lecture, comptage retournera le nombre minimum que vous puissiez compter sur; Pour le thread d'écriture comptage retournera le nombre maximum et que le décompte véritable pourrait être plus bas.

3 commentaires

Existe-t-il un risque de compilation des mises à jour dans une séquence non atomique d'étapes? C'est-à-dire tourner la dernière ligne d'écriture () dans fin + = octets; fin% = taille; ?


Le compilateur peut calculer le RHS non atomique et en fonction de votre plate-forme pourrait même stocker un int sans atomique (c'est-à-dire de stocker un Int 16 bits à l'aide de deux écrives de 8 bits sur une plate-forme 8 bits).


@ user168715, si vous ne faites absolument pas confiance à votre compilateur pour faire la bonne chose, créez une variable de code Volatile pour contenir le calcul, puis copiez-le pour la mise à jour.



2
votes

Boost fournit un tampon circulaire, mais ce n'est pas le fil sûr. Malheureusement, je ne connais aucune mise en œuvre qui est.

Le prochain standard C ++ ajoute des opérations atomiques à la bibliothèque standard, de sorte qu'ils seront disponibles à l'avenir, mais ils ne sont pas encore pris en charge par la plupart des implémentations.

Je ne vois aucune solution croisée pour garder compter sain d'esprit tandis que les deux threads y écrivent, à moins que vous n'ayez implémenter le verrouillage.

Normalement, vous utiliseriez probablement un système de messagerie et forcez le fil de la priorité faible pour demander que le thread de priorité élevée effectue des mises à jour ou quelque chose de similaire. Par exemple, si le fil à faible priorité consomme 15 octets, il devrait demander au fil hautement prioritaire de réduire le nombre de 15.

essentiellement, vous limiteriez l'accès «Écrivez» au fil de priorité élevée et permettez uniquement au fil de la priorité faible. De cette façon, vous pouvez éviter tout verrouillage et le thread de priorité élevée n'aura pas à vous soucier d'attendre que l'écriture soit remplie par le fil inférieur, rendant la priorité très prioritaire de la priorité.


0 commentaires

1
votes

boost :: interprocession offre des fonctions atomiques multiplateformes dans boost / interprocessation / détail / atomic.hpp


0 commentaires