77 votes

Comparaison des IPC Unix/Linux

Unix/linux propose un grand nombre d'IPC : pipes/sockets/mémoire partagée/dbus/files de messages. J'aimerais savoir quelles sont les applications respectives les plus appropriées, par exemple, quels sont les endroits où la mémoire partagée est préférée aux files d'attente de messages et vice versa.

Recherche également des données comparant leurs performances.

J'ai essayé de le googler et de le st_overflow mais je n'ai pas trouvé de réponse satisfaisante.

98voto

Eugene Yokota Points 43213

IPC Unix

Voici les sept principaux :

  1. Tuyau
  2. FIFO ou un tuyau nommé
  3. Prise de courant et Socket de domaine Unix
  4. File d'attente des messages
  5. Signal
  6. Sémaphore
  7. Mémoire partagée

    1. Pipe n'est utile que parmi les processus liés comme parent/enfant. Appelez pipe(2) et fork(2) . Unidirectionnel.

    2. Deux processus non liés peuvent utiliser le FIFO à la différence du plain pipe. Appeler mkfifo(3) . Unidirectionnel.

    3. Bidirectionnel. Destiné à la communication réseau, mais peut aussi être utilisé localement. Peut être utilisé pour différents protocoles. Il n'y a pas de frontière de message pour TCP. Appeler socket(2) .

    4. File d'attente de messages. L'OS maintient le message discret. Voir sys/msg.h .

    5. Le signal envoie un nombre entier à un autre processus. Ne fonctionne pas bien avec les multithreads. Appelez kill(2) .

    6. Le sémaphore est un mécanisme de synchronisation pour des processus ou des fils multiples, semblable à une file d'attente de personnes attendant des toilettes. Voir sys/sem.h .

    7. La mémoire partagée est une mémoire partagée. Faites votre propre contrôle de la concurrence. Appelez shmget(2) .

Problème de limite de message

Un facteur déterminant dans le choix d'une méthode plutôt qu'une autre est la question de la limite du message. Vous pouvez vous attendre à ce que les "messages" soient distincts les uns des autres, mais ce n'est pas le cas pour les flux d'octets comme TCP ou Pipe.

Considérons une paire de client et de serveur d'écho. Le client envoie une chaîne de caractères, le serveur la reçoit et la renvoie. Supposons que le client envoie "Hello", "Hello", et "How about an answer ?".

Avec les protocoles de flux d'octets, le serveur peut recevoir "Hell", "oHelloHow", et " about an answer ?"; ou de façon plus réaliste "HelloHelloHow about an answer ?". Le serveur ne sait pas où se trouve la limite du message.

Une vieille astuce consiste à limiter la longueur du message à CHAR_MAX ou UINT_MAX et acceptent d'envoyer le message de longueur d'abord dans char ou uint . Ainsi, si vous êtes du côté de la réception, vous devez d'abord lire la longueur du message. Cela implique également qu'un seul thread doit effectuer la lecture du message à la fois.

Avec des protocoles discrets comme UDP ou les files d'attente de messages, vous n'avez pas à vous préoccuper de ce problème, mais, sur le plan programmatique, les flux d'octets sont plus faciles à traiter car ils se comportent comme des fichiers et des stdin/out.

17voto

Judge Maygarden Points 14964

La mémoire partagée peut être la plus efficace puisque vous construisez votre propre schéma de communication au-dessus d'elle, mais elle nécessite beaucoup de soin et de synchronisation. Il existe également des solutions pour distribuer la mémoire partagée à d'autres machines.

Les sockets sont les plus portables de nos jours, mais nécessitent plus d'overhead que les pipes. La possibilité d'utiliser les sockets de manière transparente, localement ou sur un réseau, est un grand avantage.

Les files d'attente de messages et les signaux peuvent être excellents pour les applications temps réel difficiles, mais ils ne sont pas aussi flexibles.

Ces méthodes ont été naturellement créées pour la communication entre les processus, et l'utilisation de plusieurs threads au sein d'un processus peut compliquer les choses - notamment avec les signaux.

10voto

Phillip Whelan Points 952

Je suis également intéressé à connaître les différences.

Voici une page web avec un benchmark simple : http://www.rikkus.info/sysv-ipc-vs-unix-pipes-vs-unix-sockets

Pour autant que je sache, chacun a ses avantages :

  • L'entrée/sortie par tube est la plus rapide, mais elle nécessite une relation parent/enfant pour fonctionner.
  • Sysv IPC a une frontière de message définie et peut connecter localement des processus disparates.
  • Les sockets UNIX peuvent connecter localement des processus disparates et disposent d'une bande passante plus élevée mais pas de limites inhérentes aux messages.
  • Les sockets TCP/IP peuvent connecter n'importe quel processus, même sur le réseau, mais ils ont une surcharge plus importante. et aucune limite inhérente aux messages.

8voto

MarkR Points 37178

Il est intéressant de noter que de nombreuses bibliothèques implémentent un type de chose par-dessus un autre.

La mémoire partagée n'a pas besoin d'utiliser les horribles fonctions de mémoire partagée de sysv - il est beaucoup plus élégant d'utiliser mmap() (mmap un fichier sur un tmpfs /dev/shm si vous voulez qu'il soit nommé ; mmap /dev/zero si vous voulez que les processus forkés et non exécutés héritent de ce fichier anonymement). Ceci dit, vos processus ont toujours besoin d'une certaine synchronisation pour éviter les problèmes - typiquement en utilisant certains des autres mécanismes IPC pour synchroniser l'accès à une zone de mémoire partagée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X