Quel IPC est le plus efficace ici?

J’ai une application système qui fonctionne comme une collection sur 12 processus sur unix. Il existe un processus de surveillance qui échange des données avec 11 autres processus.

L’exigence de l’IPC consiste à faire en sorte que ces 11 processus communiquent avec le processus de surveillance, conçu de la manière la plus efficace en termes d’exécution. Pouvez-vous peser les deux options ci-dessous ou en proposer une meilleure?

1) avoir une communication par socket UDP, où ces 11 processus transmettent les données au processus de surveillance à intervalles réguliers. le processus de surveillance consiste simplement à écouter et à capturer des informations, ce qui est suffisant.

OU

2) avoir une implémentation de mémoire partagée. il y a donc 11 segments de mémoire partagée, où chacun est partagé entre 2 processus (traitement et processus de surveillance).

Pour la mémoire partagée, cela semble plus rapide, mais un locking / synchronisation est nécessaire, car comme dans udp, le kernel copie les données de l’espace mémoire d’un processus vers l’autre.

Quelqu’un peut-il fournir plus d’intrants pour aider à mieux évaluer les deux méthodes. ? Merci.

La coordination de la mémoire partagée est délicate. Le parent doit savoir quand lire quelle partie de chacun des 11 segments de la mémoire partagée, et laisser savoir à l’enfant quand les données ont été lues pour qu’une partie de la mémoire partagée puisse être réutilisée, etc. plus rapidement, le rest de la coordination (peut-être en utilisant des ensembles de sémaphores – peut-être avec 22 sémaphores, un pour chaque direction des 11 canaux de communication) signifie que vous trouverez certainement un mécanisme beaucoup plus facile à coder. Les appels système select() ou poll() ou variant peuvent être utilisés pour vous indiquer quand le maître doit lire des données. Et le kernel traite tous les problèmes désagréables de la planification et du contrôle des stream, etc.

Donc, utilisez des sockets Unix-domain à moins que vous ne puissiez vraiment démontrer que vous obtiendrez un avantage en termes de performances grâce à la version à mémoire partagée. Mais attendez-vous à perdre des cheveux (et quelques données) pour que l’implémentation de la mémoire partagée soit correcte. (Vous pouvez démontrer si l’utilisation de la mémoire partagée avec un système brutal et mal synchronisé présente un avantage en termes de performances; vous n’entrerez probablement pas en production avec un système brutalement mal synchronisé.)

Cela dépend beaucoup de la quantité de données que les processus doivent partager les uns avec les autres. S’il y a beaucoup de données (par exemple, des mégaoctets ou des gigaoctets) transmises, la mémoire partagée sera la solution la plus efficace. Si la quantité de données est limitée (kilo-octets ou quelques mégaoctets), une approche basée sur les sockets est probablement préférable, car l’efficacité n’aura pas beaucoup d’importance et éviter la mémoire partagée rendra votre système plus robuste et plus fiable. plus facile à développer et à déboguer.

En outre, certains kernelx prennent en charge la mise en réseau sans copie, auquel cas l’envoi de paquets UDP d’un processus à un autre peut ne pas nécessiter la copie des données, mais simplement le remappage des pages MMU sous-jacentes dans le processus de destination. Si tel est le cas, l’approche Sockets vous offrira le meilleur des deux mondes (efficacité ET robustesse).

Dans UDP, la livraison n’est pas garantie et il arrive que des paquets soient supprimés, même dans les communications localhost. Donc, les fonds monétaires seraient probablement meilleurs.