2009-09-08 7 views
2

Hokay donc j'ai une application où j'ai besoin de l'IPC ... Je pense que les pipes nommées sont la voie à suivre parce qu'elles sont si faciles à utiliser.Stratégies de tuyau nommées avec mémoire dynamique?

De toute façon, j'ai une question sur la façon de gérer la mémoire dynamique en utilisant des tuyaux nommés.

Dire que j'ai une classe comme celle-ci:

class MyTestClass { 
public: 
    MyTestClass() { _data = new int(4); } 

    int GetData() { return *_data; } 
    int GetData2() { return _data2; } 

private: 
    int* _data; 
    int _data2; 
}; 

Maintenant, quand je crée un tampon pleine de MyTestClass objets puis les envoyer sur le tuyau, je perds évidemment _data dans le processus de destination et d'obtenir les ordures . Y at-il une stratégie à ce que je devrais utiliser? Je peux utiliser des types de valeurs pour des cas simples, mais pour de nombreuses classes complexes, j'ai besoin d'utiliser une sorte de mémoire dynamique et j'aime les pointeurs. Ou, devrais-je simplement regarder à l'aide de la mémoire partagée à la place? Merci

+0

Je pense que vous devriez supprimer '_data2' et whatnot. Ce n'est pas complet (initialisé) et je pense que votre question est claire sans elle de toute façon. – GManNickG

+0

Puisque votre constructeur alloue de la mémoire, vous avez besoin d'un destructeur pour libérer cette mémoire, n'est-ce pas? –

+0

oui je ai besoin de le libérer, désolé pour la mauvaise forme ... je voulais juste faire passer le point – Polaris878

Répondre

3

Les canaux nommés et la mémoire partagée ont des problèmes similaires: Vous devez sérialiser le contenu de la structure dans le côté de l'envoi et désérialiser la structure du côté réception.

Le processus de sérialisation est essentiellement identique que vous utilisiez des canaux nommés ou de la mémoire partagée. Pour les pointeurs incorporés (comme _data et _data2), vous devez sérialiser le contenu du pointeur de manière cohérente.

Il existe de nombreuses stratégies de sérialisation que vous pouvez utiliser en fonction de la disposition de vos structures en mémoire et de l'efficacité de votre IPC. Ou vous pouvez utiliser DCE RPC et laisser le code de marshaling RPC gérer les complexités pour vous.

+0

Merci pour la réponse ... des conseils sur les protocoles que je pourrais utiliser ou des stratégies de sérialisation que je pourrais utiliser? Merci – Polaris878

+0

Si vous cherchez des stratégies de sérialisation, le cas le plus fréquent est le stockage de fichiers. Comment écrire votre classe dans un fichier et le relire plus tard? Vous pourriez être en mesure de vous épargner beaucoup de travail si vous encapsulez votre canal IPC en tant que 'std :: streambuf'; De cette façon, vous pouvez partager et réutiliser beaucoup de code. – MSalters

+0

MSalters a pris les mots de ma bouche. Sa suggestion est sur place. –

1

Pour envoyer les données via un canal nommé, vous devez sérialiser (ou marshaler) les données à l'extrémité émettrice et les désérialiser (ou les masquer) à l'extrémité réceptrice.

Cela ressemble étrangement à une simple copie des octets dans la structure de données. Ce n'est pas bon du tout. Vous ne copiez pas les données allouées (elles ne sont pas stockées entre le premier et le dernier octet de la structure de données, mais ailleurs) et vous copiez un pointeur (_data) d'une machine (ou d'un processus) vers une autre, l'adresse mémoire dans le processus local n'a pas de signification garantie dans l'autre. Définissez vous-même un protocole de fil (si désespéré, regardez ASN.1 - non, à la réflexion, ne soyez pas si désespéré) qui définit la disposition des données pour la transmission sur le fil. Ensuite, implémentez les fonctions émetteur et récepteur (ou seralizer et deserializer). Ou trouvez le code de quelqu'un d'autre qui le fait déjà. N'oubliez pas de traiter avec endian-ness - vous devez définir la séquence dans laquelle les octets sont envoyés via le canal nommé. Par exemple, vous pouvez définir que le message envoyé est constitué d'un entier non signé de 4 octets dans l'ordre des octets réseau, définissant le nombre de structures à suivre et chaque structure pouvant être une séquence de 4 entiers signés à 4 octets pour le tableau par un seul entier signé de 4 octets pour _data2 (également envoyé dans l'ordre des octets du réseau). Notez que le choix du tube nommé comme mécanisme IPC est largement non significatif; sauf si vous utilisez de la mémoire partagée (de manière inhérente sur la même machine), alors endian-ness doit être traité, et même avec de la mémoire partagée, vous devez gérer la sérialisation.

+0

Merci ... C'est ce que je pensais ... Je suis un peu nouveau dans le domaine de l'IPC. À l'heure actuelle, je n'envoyais que des octets bruts à travers haha ​​... Je voulais voir quelles étaient les limites de ces mécanismes IPC. Vous avez raison de dire que les octets ne sont pas dans la structure de données ... c'est exactement le problème que j'essayais de résoudre. – Polaris878

Questions connexes