Comparaison des IPC Unix/Linux
4 réponses
Unix IPC
Voici les sept grands:
-
N'est utile que dans les processus parent/enfant. Appeler
pipe(2)
etfork(2)
. Unidirectionnel. -
FIFO , ou pipe dénommée
deux les procédés non liés peuvent utiliser FIFO contrairement à la pipe ordinaire. Appel
mkfifo(3)
. Unidirectionnel. -
Socket et Socket de Domaine Unix
bidirectionnel. Signifiait pour la communication en réseau, mais peut être utilisé localement. Peut être utilisé pour un protocole différent. Il n'y a pas de limite de message pour TCP. Appel
socket(2)
. -
OS maintient un message discret. Voir sys / msg.h .
-
Le Signal
envoie un entier à un autre processus. Ça ne colle pas bien avec le multi-threads. Appel
kill(2)
. -
un mécanisme de synchronisation pour des processus ou des fils multiples, similaire à une file d'attente de personnes en attente de salle de bains. Voir sys / sem.h .
-
faites votre propre contrôle de concurrence. Appel
shmget(2)
.
Message La question des limites
un facteur déterminant dans le choix d'une méthode par rapport à l'autre est la question de la limite du message. Vous pouvez vous attendre à ce que les "messages" soient discrets les uns des autres, mais ce n'est pas pour les flux d'octets comme TCP ou Pipe.
considère une paire de client et de serveur echo. Le client envoie la chaîne de caractères, le serveur la reçoit et la renvoie directement. Supposons que le client envoie "Bonjour", "bonjour", et "Que Diriez-vous d'une réponse?".
avec byte stream protocoles, le serveur peut recevoir comme "Hell", "oHelloHow", et " à propos d'une réponse?"; ou de manière plus réaliste "HelloHelloHow au sujet d'une réponse?". Le serveur n'a aucune idée où se trouve la limite du message.
une vieille astuce consiste à limiter la longueur du message à CHAR_MAX
ou UINT_MAX
et à accepter d'envoyer la longueur du message en premier dans char
ou uint
. Donc, si vous êtes du côté de la réception, vous devez d'abord lire la longueur du message. Cela implique également que seulement un fil devrait faire la lecture du message à la fois.
avec des protocoles discrets comme UDP ou des files d'attente de messages, vous n'avez pas à vous soucier de ce problème, mais programmatically byte streams sont plus faciles à traiter parce qu'ils se comportent comme des fichiers et stdin/out.
la mémoire partagée peut être la plus efficace puisque vous construisez votre propre schéma de communication sur elle, mais elle exige beaucoup de soins et de synchronisation. Des Solutions sont également disponibles pour distribuer la mémoire partagée à d'autres machines.
Les douillessont les plus portatives de nos jours, mais elles nécessitent plus d'espace aérien que les tuyaux. La possibilité d'utiliser des sockets de manière transparente localement ou sur un réseau est un grand bonus.
les files d'attente et les signaux de messages peuvent être idéal pour les applications difficiles en temps réel, mais ils ne sont pas aussi flexibles.
ces méthodes ont été créées naturellement pour la communication entre les processus, et l'utilisation de fils multiples dans un processus peut compliquer les choses-en particulier avec des signaux.
Voici une page Web avec un benchmark simple: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
autant que je sache, chacun a ses avantages:
- canal d'e/S est le plus rapide, mais a besoin d'une relation parent/enfant au travail.
- Sysv IPC a une limite de message définie et peut connecter des processus disparates localement.
- Unix sockets peut connecter des processus disparates localement et a une bande passante plus élevée mais aucune limite de message inhérente.
- TCP/IP sockets peuvent connecter tous les processus, même sur le réseau, mais a des frais généraux plus élevés et pas de limites inhérentes aux messages.
il est intéressant de noter que beaucoup de bibliothèques mettent en œuvre 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 sysv - c'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 forked Non exec'd héritent anonymement). Cela dit, il reste encore un besoin de synchronisation de vos processus pour éviter les problèmes-typiquement en utilisant certains des autres mécanismes de la CIB pour synchroniser l'accès à une zone de mémoire partagée.