Nous avons besoin de plusieurs programmes pour appeler des fonctions dans une bibliothèque commune. La bibliothèque fonctionne et accède à une mémoire globale commune. Les appels de fonction de chaque programme doivent voir cette mémoire globale commune. C'est un appel de fonction a besoin de voir les mises à jour de tout appel de fonction préalable même si appelé d'un autre programme. Pour des raisons de compatibilité, nous avons plusieurs contraintes de conception sur la façon dont les fonctions exposées par la bibliothèque partagée doit fonctionner:Instanciation d'objets dans la mémoire partagée C++
- Tous les éléments de données (les deux types de données standard et objets) qui sont déclarés globalement doivent être visibles pour tous les appelants quel que soit le thread dans lequel le code est en cours d'exécution.
- Tous les éléments de données déclarés localement dans une fonction sont uniquement visibles dans cette fonction.
- Tout type de données standard ou une instance de n'importe quelle classe peut apparaître localement ou globalement ou les deux.
Une solution consiste à placer la mémoire globale commune de la bibliothèque dans la mémoire partagée nommée. Le premier appel de bibliothèque créerait la mémoire partagée nommée et l'initialiserait. Les appels de programme suivants obtiendraient l'adresse de la mémoire partagée et l'utiliseraient comme un pointeur vers la structure de données globale. Les instances d'objets déclarées globalement doivent être allouées dynamiquement dans la mémoire partagée tandis que les instances d'objets déclarées localement peuvent être placées sur la pile ou dans le tas local du thread appelant. Des problèmes surviennent parce que les objets initialisés dans la mémoire globale peuvent créer et pointer vers des sous-objets qui allouent (nouvelle) de la mémoire supplémentaire. Ces nouvelles allocations doivent également être dans la mémoire partagée et être vues par tous les appelants de bibliothèque. Une autre complication est que ces objets, qui contiennent des chaînes, des fichiers, etc., peuvent également être utilisés dans le programme appelant. Lorsqu'il est déclaré dans le programme appelant, la mémoire de l'objet est locale au programme appelant, non partagée. Le code de l'objet doit donc gérer les deux cas. Il nous semble que la solution exigera que nous remplacions le placement global par de nouveaux opérateurs réguliers, nouveaux et supprimés. Nous avons trouvé une conception pour un système de gestion de la mémoire qui semble fonctionner, mais nous n'avons trouvé aucune implémentation réelle. Si quelqu'un connaît une implémentation de la gestion de la mémoire de Nathan Myers (http://www.cantrip.org/wave12.html?seenIEPage=1) j'apprécierais un lien vers celui-ci. Sinon, si quelqu'un connaît un autre gestionnaire de mémoire partagée qui permet d'allouer dynamiquement des objets, j'aimerais aussi le savoir. J'ai vérifié les bibliothèques Boost et toutes les autres sources que je peux trouver mais rien ne semble faire ce dont nous avons besoin. Nous préférons ne pas avoir à en écrire un nous-mêmes. Puisque la performance et la robustesse sont importantes, il serait bon d'utiliser du code éprouvé. Merci d'avance pour toute idée/aide.
Merci pour les suggestions sur les bibliothèques ATL et OSSP. Je les vérifie maintenant même si j'ai peur que l'ATL soit trop Wincentric si la cible s'avère être Unix.
Une autre chose nous semble maintenant claire. Étant donné que les objets peuvent être créés dynamiquement pendant l'exécution, le schéma de gestion de la mémoire doit être capable d'allouer des pages supplémentaires de mémoire partagée. Cela commence maintenant à ressembler à un gestionnaire de mémoire de remplacement de tas à part entière.
La solution canonique à ce problème n'est-elle pas de créer un serveur que les applications clientes peuvent utiliser? Beaucoup plus facile que de rester avec la mémoire partagée, ce qui est peu probable pour les raisons que vous donnez. –
D'accord avec Neil. – wheaties
Oui. La refonte de l'application serait le moyen le plus simple de résoudre le problème. Malheureusement, en raison des contraintes de conception dues à la compatibilité avec d'autres composants, nous n'avons pas cette option. – BillC