web-dev-qa-db-fra.com

La technique la plus rapide pour passer des messages entre processus sur Linux?

Quelle est la technologie la plus rapide pour envoyer des messages entre les processus d’application C++, sous Linux? Je suis vaguement conscient que les techniques suivantes sont sur la table:

  • TCP
  • UDP
  • Sockets
  • Les pipes
  • Tuyaux nommés
  • Fichiers mappés en mémoire

y a-t-il d'autres moyens et quel est le plus rapide? 

29
user997112

Je suggérerais également de regarder ceci: Comment utiliser la mémoire partagée avec Linux en C .

Fondamentalement, j'abandonnerais les protocoles réseau tels que TCP et UDP lorsque vous exécuteriez IPC sur un seul ordinateur. Ceux-ci entraînent une surcharge de paquets et sont liés à encore plus de ressources (par exemple, ports, interface de bouclage).

13
Sam

Bien que toutes les réponses ci-dessus soient très bonnes, je pense que nous devrions discuter de ce qui est "le plus rapide" [et faut-il que ce soit "le plus rapide" ou juste "assez rapide pour"?]

Pour les messages LARGE, il ne fait aucun doute que la mémoire partagée est une très bonne technique, et très utile à bien des égards. 

Toutefois, si les messages sont petits, vous devrez présenter votre propre protocole de transmission de message et une méthode permettant d’informer l’autre processus de la présence d’un message. 

Les tubes et les tubes nommés sont beaucoup plus faciles à utiliser dans ce cas - ils se comportent assez bien comme un fichier, vous écrivez simplement des données du côté de l'envoi et lisez les données du côté de la réception. Si l'expéditeur écrit quelque chose, le récepteur se réveille automatiquement. Si le canal est plein, le côté d'envoi est bloqué. S'il n'y a plus de données provenant de l'expéditeur, le destinataire est automatiquement bloqué. Cela signifie que cela peut être implémenté dans assez peu de lignes de code avec une assez bonne garantie qu'il fonctionnera à tout moment, à tout moment. 

D'autre part, la mémoire partagée repose sur un autre mécanisme pour informer l'autre thread que "vous avez un paquet de données à traiter". Oui, c'est très rapide si vous devez copier de GRANDS paquets de données - mais je serais surpris qu'il y ait une énorme différence par rapport à un tuyau. Le principal avantage serait que l’autre côté n’a pas à copier les données de la mémoire partagée - mais il faut aussi qu’il y ait assez de mémoire pour conserver tous les messages "en vol" ou que l’expéditeur ait la capacité de retenir des choses. . 

Je ne dis pas "n'utilisez pas de mémoire partagée", je dis simplement qu'il n'existe pas de solution comme "une solution qui résout le mieux tous les problèmes" ". 

Pour clarifier: je commencerais par mettre en œuvre une méthode simple en utilisant un tuyau ou un tuyau nommé [en fonction de ce qui convient aux objectifs] et en mesurer les performances. Si vous passez vraiment beaucoup de temps à copier les données, j’envisagerais d’utiliser d’autres méthodes. 

Bien entendu, une autre considération devrait être "allons-nous jamais utiliser deux machines distinctes [ou deux machines virtuelles sur le même système] pour résoudre ce problème. Dans ce cas, une solution réseau est un meilleur choix - même si ce n'est pas LA solution la plus rapide. , J’ai exécuté une pile TCP locale sur mes machines au travail à des fins de comparaison et j’ai obtenu environ 20-30 Gbit/s (2-3 Go/s) avec un trafic soutenu. Une mémoire brute au sein du même processus génère environ 50 -100 Go/s (5 à 10 Go/s) (sauf si la taille du bloc est VRAIMENT minuscule et s'inscrit dans le cache L1). Je n'ai pas mesuré de tuyau standard, mais je m'attends à ce qu'il se situe à peu près au milieu de ces deux chiffres. [Ces chiffres sont à peu près corrects pour un certain nombre de PC de taille moyenne assez modernes - de toute évidence, sur un contrôleur de style intégré, MIPS ou autre, attendez-vous à un nombre inférieur pour toutes ces méthodes]

37
Mats Petersson

Le groupe de recherche sur les systèmes NetOS de l’Université de Cambridge, au Royaume-Uni, a réalisé quelques tests de performance (open source) IPC. 

Le code source se trouve à https://github.com/avsm/ipc-bench

Page du projet: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ .

Résultats: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

Cette recherche a été publiée en utilisant les résultats ci-dessus: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf

7
DejanLekic

Vérifiez CMA et kdbus: https://lwn.net/Articles/466304/

Je pense que les produits les plus rapides de nos jours sont basés sur AIO . http://www.kegel.com/c10k.html

3
Alex

Comme vous avez balisé cette question avec C++, je vous recommanderais Boost.Interprocess :

La mémoire partagée est le mécanisme de communication interprocessus le plus rapide. Le Le système d'exploitation mappe un segment de mémoire dans l'espace d'adressage de plusieurs processus, de sorte que plusieurs processus puissent lire et écrire dans cette mémoire segment sans appeler les fonctions du système d'exploitation. Cependant, nous avons besoin de une sorte de synchronisation entre les processus qui lisent et écrivent la memoire partagée.

La source

Un inconvénient que j'ai trouvé est le limitations de portabilité pour les primitives de synchronisation . Ni OS X, ni Windows n'ont d'implémentation native pour les variables de condition interprocessus, par exemple, .__ et les émulent donc avec des verrous pivotants.

Maintenant, si vous utilisez un * nix prenant en charge les primitives partagées du processus POSIX, il n'y aura aucun problème.

La mémoire partagée avec synchronisation est une bonne approche lorsque des données considérables sont impliquées.

2
pepper_chico

Eh bien, vous pourriez simplement avoir un segment de mémoire partagée entre vos processus, en utilisant la mémoire partagée de Linux aka SHM.

C'est assez facile à utiliser, regardez le lien pour quelques exemples.

1
cmc

Les files de messages posix sont assez rapides mais ont quelques limitations

0
arash kordi