9
votes

Mécanismes de verrouillage pour la cohérence partagée-mémoire

Je développe un mécanisme permettant d'interchangeer des données entre deux processus ou plus à l'aide de la mémoire partagée sur Linux. Le problème est que certains niveaux de contrôle de la concurrence sont nécessaires pour maintenir l'intégrité des données sur la mémoire partagée elle-même, et, comme je m'attends à ce que, parfois, mon processus puisse être tué / crash, des mécanismes de verrouillage communs ne fonctionnent pas car ils pourraient quitter le mémoire dans un état "verrouillé" et juste après la mort, ce qui rend d'autres processus suspendus à la libération de la serrure.

Donc, faire des recherches que j'ai trouvées que System v Semaphores ait un drapeau appelé Sem_undo, qui peut revenir à l'état de verrouillage lorsque le programme échoue, mais cela n'est pas garanti de travailler. Une autre option consiste à surveiller les PID de tous les processus qui pourraient utiliser la mémoire partagée et faire un certain contrôle sur eux si quelque chose de méchant se passe, mais je ne suis pas sûr que cela puisse être la bonne approche de mon problème.

Des idées?

Edit: À des fins d'explication, notre application nécessite une sorte de mécanisme IPC avec la plus petite latence possible. Donc, je suis ouvert aux mécanismes qui peuvent également gérer cette exigence.


6 commentaires

Encore une autre alternative ne doit pas utiliser de mémoire partagée - je n'ai jamais compris la fascination terrible qu'elle semble contenir pour les programmeurs. Il y a beaucoup d'autres mécanismes IPC (certains pré-construits et testés sur la mémoire partagée), alors pourquoi ne pas les utiliser?


Pour la performance. Notre application doit fonctionner sur la latence microseconde. Il existe des mécanismes IPC qui peuvent atteindre cette performance?


@scoermann que la variante Linux en temps réel utilisez-vous?


@Neil En fait, je n'utilise pas de RT Linux. Mais en utilisant SharedMem comme système de "file d'attente", j'ai atteint 6 microsecs par message.


Cette "terrible fascination" a tendance à provenir du fait que la mémoire partagée est généralement la forme la plus rapide de la CIP.


@Bobby je vois, alors pouvez-vous faire un post avec une meilleure option, s'il vous plaît? Merci! = D


5 Réponses :


2
votes

Il n'y a que peu de choses qui sont garanties pour être nettoyées d'où un programme échoue. La seule chose qui me vient à mon esprit ici, ce sont des comptes de liaison. Un descripteur de fichier ouvert augmente le nombre de liais de l'inode sous-jacent et une fermeture correspondante diminue, y compris une fermeture forcée lorsque le programme échoue.

Donc, vos processus pourraient tous ouvrir un fichier commun (ne vous rappelez pas si cela fonctionne pour des segments de mémoire partagée) et vous pouvez déclencher une sorte d'alarme si le nombre diminue, où cela ne devrait pas. E.g Au lieu de faire une attente simple, vos processus pouvaient faire une tendresse (pour un second, par exemple) dans une boucle et un sondage pour que le nombre de liens soit alerté lorsque quelque chose se passe mal.


2 commentaires

La question est marquée avec POSIX. Les futurs FUTEX IIRC sont des constructions Linux pures et non portables pour d'autres systèmes POSIX.


Après une pensée, une structure de verrouillage est conforme à POSIX et est garantie d'être nettoyée sur la terminaison de processus: serrures de fichier consultatif au moyen de FCNTL. Ils sont un peu difficiles à utiliser (pièges: vous perdez une serrure lorsque la FD sur la même inode est fermée par l'une quelconque des threads du processus) mais sont entièrement réalisées dans l'espace du noyau et rien n'est réellement écrit sur le disque.



1
votes

Lorsque vous avez déclaré que les sémaphores ne peuvent pas gérer de manière proprement des processus, j'étais un peu surpris. Ce type de soutien semble assez fondamental! En regardant la page de l'homme de Semop Semop sur mon système Ubuntu 10.4 et sur le Web ici semble suggérer que cela devrait être ok. Espérons que la mémoire utilisée pour stocker le nombre SEM_undo est stockée dans l'espace du noyau et, partant, à l'abri des écritures de mémoire errant.

La vérité se dit cependant, même un mécanisme de verrouillage de sémaphore fiable pourrait ne pas résoudre complètement votre problème. Si vous utilisez des serrures pour permettre le traitement de la transaction, vous devrez également gérer des situations dans lesquelles la transaction est arrêtée à part avant de s'écraser et permettra à un autre programme d'accéder à la structure de données.


1 commentaires

Désolé, je n'ai pas trouvé la source d'où j'ai lié cela. Bien que les sémaphores du système IV ont une limitation d'environ 37 000 structures SEM_undo pouvant être détenues par le processus, il ne fonctionnerait donc de toute façon que mon application peut écrire ce montant de messages très rapide. Merci quand même.



1
votes

Je serais curieux de savoir quelle source vous utilisiez que Sem_undo n'était pas garanti de travailler. Je n'ai pas entendu cela auparavant. Je semble me souvenir de lire des articles affirmant que Sysv IPC de Linux en général était Buggy mais cela a été assez di. Je me demande si vos informations sont juste un artefact de fois passé.

L'autre chose à considérer (si je me souviens bien), les sémaphores SYSV ont la capacité de vous indiquer le PID du dernier processus d'exécution d'une opération de sémaphore. Si vous accrochez, vous devriez pouvoir interroger si le processus tenant la serrure est toujours en vie. Depuis tout processus (non seulement celui qui tient le verrou) peut jouer avec un sémaphore, vous pourriez exercer un contrôle de cette façon.

Enfin, je vais mettre dans une hauteur des files d'attente de message. Ils pourraient ne pas être appropriés pour vos besoins de vitesse, mais ils ne sont généralement pas beaucoup plus lents que la mémoire partagée. En substance, ils font tout ce que vous devez faire manuellement avec SM de toute façon, mais le système d'exploitation fait tout cela sous les couvertures. Vous obtenez presque autant de vitesse avec la synchronisation, l'atomicité, la facilité d'utilisation et un mécanisme testé à travers gratuitement.


1 commentaires

Je vais prendre cela comme accepté parce que j'ai changé de files d'attente de messages et que je l'ai jugée adaptable à mes besoins. Merci



1
votes

Vous pouvez utiliser un Pthread Mutex dans la mémoire partagée Pthread_Mutexattr_setPshared ( http: //linux.die. NET / MAN / 3 / PTHEAD_MUTEXATTR_SETPSHARED )

Aussi, vous pouvez essayer d'utiliser des futexs directement voir http://people.redhat.com/ drepper / futex.pdf et http: / /lxr.linux.no/#linux+v2.6.34/documentation/robust-futexes.txt et http://www.kernel.org/doc/man-pages/online/pages/man7/futex.7.html et http://www.kernel.org/doc/ Pages de l'homme / en ligne / Pages / Man2 / Futex.2.html De particulariaLy Le second depuis que cela parle d'obtenir le noyau de le libérer lorsqu'un processus tenant la matrice.

Aussi, je pense que il est possible de rendre les Serrures / CVS de Pthreads robustes, ce qui constitue une meilleure idée, car tout ce qui permet de manipuler des verrous robustes est effectué pour vous (dans une distribution moderne même à distance, il devrait utiliser les futurs Fuex décrits. dans http://lxr.linux.no/#Linux + v2.6.34 / documentation / robust-futexes.txt pour pthread_mutex IIRC Depuis que cela fait partie du noyau depuis un certain temps, mais vous voudrez peut-être vous assurer de ne pas avoir besoin de faire quoi que ce soit pour rendre votre pthread_mutex robuste )


0 commentaires

3
votes

Ainsi, faire des recherches que j'ai trouvées que System v Semaphores ait un drapeau appelé Sem_undo Wich peut revenir à l'état de verrouillage lorsque le programme échoue, mais ce n'est pas garanti de travailler.

SEM_undo débloquerait le sémaphore si le processus se bloque. Si les processus se sont écrasés en raison de la corruption de la mémoire partagée, rien de sémaphores ne peut faire pour vous. OS ne peut pas annuler l'état de la mémoire partagée.

Si vous avez besoin d'être en mesure d'annuler l'état de la mémoire partagée, vous devez mettre en œuvre quelque chose par vous-même. J'ai vu au moins deux modèles qui traitent de cela.

premier modèle avant de modifier quoi que ce soit dans la mémoire partagée prenait un instantané de la structure, enregistré dans une liste dans la mémoire partagée. Si un autre processus a été capable d'obtenir la serrure et que la liste n'était pas vide, elle éteignait tout ce que le processus écrasé aurait peut-être changé.

Deuxième modèle consiste à faire des copies des structures SHM dans la mémoire locale et à maintenir la serrure verrouillée pour toute la transaction. Lorsque la transaction est commise, avant de relâcher la serrure, copiez simplement les structures de la mémoire locale dans la mémoire partagée. Probabilité que l'application se bloque pendant la copie soit plus faible et que l'intervention des signaux externes peut être bloquée à l'aide de sigprocmask () . (Verrouillage dans le cas mieux être bien partitionné sur les données. E. g. J'ai vu des tests avec ensemble de 1000 serrures pour 10 mln enregistrements dans SHM accessible par 4 processus concurrents.)


1 commentaires

Trucs très intéressants. Merci!