IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Transfert de structure entre 2 applications


Sujet :

Threads & Processus C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut Transfert de structure entre 2 applications
    Bonjour,

    Je dois transfert une structure de données (float et doubles) d'une application à une autre sur un même pc sous windows. Il m'a semblé intéressant d'utiliser les process IPC cependant je ne sais pas trop lequel choisir. J'hésite notamment entre passer mes données par de la mémoire partagée avec du filemapping ou alors utiliser un pipe.

    J'aurais aimé avoir quelques informations concernant ces processus et éventuellement quelques exemples de codes (notamment pour les pipes ).

    Merci d'avance

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    J'aurais tendance à dire que tout dépend de la taille de la structure, et de combien de fois par seconde tu dois la transférer...

    La mémoire partagée est, à mon avis, plus simple à implémenter que le pipe (qui se comporte à peu près comme un fichier / socket, donc avec un peu de gestion pour vérifier s'il y a des données ou pas).

    La mémoire partagée, elle, est vue comme un tableau, qu'il faudra protéger via un mutex nommé et une section critique située dans la mémoire partagée elle-même. Ce n'est pas bien difficile, seule la décision de passage de l'information est gênante (l'idéal étant d'avoir un thread par processus dédié à ça).

    Pour ma part, je préfère la mémoire partagée parce qu'elle n'est pas tributaire d'une taille ou d'une communication particulière : tu peux parfaitement avoir une application "maître", qui crée cette mémoire et lance les signaux indiquant qu'une donnée est prête, tandis que derrière de multiples applications "esclaves" peuvent alors récupérer les données.

    Les pipes, eux, sont d'une application à l'autre, ce qui est plus restrictif... Toutefois, pour de gros volumes de données et/ou des données fréquentes et/ou un flux constant, ils sont bien plus efficaces que la mémoire partagée.

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Ma structure n'est pas énorme (20 valeurs de type float au maximum), par contre je recherche une grosse vitesse d'accès afin d'avoir une base de donnée actualisée très souvent.

    Je débute dans les processus IPC, j'ai déjà pas mal regardé la mémoire partagée et les mutex et la j'ai quelques soucis de synchronisation d'accès. Qu’entends-tu par avoir un thread par processus dédié à la décision de passage de l'information? Que doivent-ils faire?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 369
    Points
    50 369
    Par défaut
    Si ce que tu dois gérer doit être vu comme une base de données (partagée), je partirai vers une mémoire partagée protégée par un sémaphore.

    Le gestionnaire principal des données (l'écrivain) créé la mémoire partagée et le sémaphore. Quand il veut écrire dedans, il prend le sémaphore et le libère quand il a finit d'écrire.

    Les lecteurs quand ils veulent lire prennent le sémaphore, lisent la mémoire partagée et libèrent le sémaphore.

    Après les moyens pour implémenter cela dépendent de ton architecture.

    Sous Windows, je partirai vers CreateFileMapping() et ses petites soeurs pour le segment de mémoire partagée (regarde ici pour une introduction) et vers CreateSemaphore() pour le sémaphore.

    Sinon, tu peux aussi voir du côté de boost s'il y a des équivalents ou alors du côté des appel SYSV (shmget et semget)

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par OttisToole Voir le message
    Ma structure n'est pas énorme (20 valeurs de type float au maximum), par contre je recherche une grosse vitesse d'accès afin d'avoir une base de donnée actualisée très souvent.
    Mémoire partagée alors.

    Citation Envoyé par OttisToole Voir le message
    Qu’entends-tu par avoir un thread par processus dédié à la décision de passage de l'information? Que doivent-ils faire?
    Les threads "consommateurs" (appelés aussi "lecteurs") sont en attente bloquante d'un mutex / sémaphore : un mutex si un seul doit pouvoir lire en même temps, et sémaphore s'ils peuvent être plusieurs à lire simultanément.

    Quand le "producteur" (aussi appelé "rédacteur") veut mettre les données à jour, il prends le contrôle de la mémoire partagée de façon exclusive (mutex le plus souvent), mets la donnée à jour, libère les threads consommateurs puis relâche la table.

    Cela se règle habituellement avec un mutex de table, plus un mutex/sémaphore d'accès aux données. Le mutex de la table protège "physiquement" en fait l'accès au sous-mutex, qui lui protège "logiquement" les données.
    Le premier empêche donc les bêtises (blocage réel d'un accès concurrent non autorisé), le second définit qui a le droit d'accès.

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Merci des indications, je vais tenter d'implémenter tout ca

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    J'arrive un peu après la bataille, mais bon... Globalement, je partage les indications données pour la mémoire partagée, mais j'amène quelques remarques :
    1/ Attention à ce que le mécanisme de synchronisation pour l'accès ne soit pas pénalisant par rapport à un autre canal d'échange. Fais quelque chose de générique qui te permette de rapidement changer d'un mode d'échange à un autre pour faire ensuite un bench sur les performances ;
    2/ Et j'en viens au second point. Tu construits un système en 2 applications distinctes sur le même poste. D'expérience, le client a souvent (mais pas toujours) dans un deuxième temps le souhait de déporter une des 2 applications sur un poste différent. Et là, la mémoire partagée Évalue ce risque par rapport à ton système.

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Et là, la mémoire partagée Évalue ce risque par rapport à ton système.
    Habituellement, je pallie ce problème via une "application" spécifique cachée (habituellement un thread lancé depuis une DLL, voire un processus à part entière lancé par l'application principale) qui utilise une communication par sockets, puis "publie" dans la mémoire partagée le résultat.

    Ainsi, tous les clients sur le même poste bénéficient de la mémoire partagée, plus rapide, mais un déport sur d'autres postes reste possible. Seules les données devant "changer" de machine sont alors expédiées par le réseau.

  9. #9
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Pour ce transfert de donnée, il n'y aura pas de transfert via le réseau. Je vais faire ca dans une deuxième temps par l'appli "consommatrice". J'aurais besoin de quelques éclaircissements surtout a propos de tes techniques de multithreading Mac Lak .

    un bench sur les performances
    Qu'entends tu par la?

    Vu que j'ai que deux applications et que les actions sur ma mémoire partagée vont se résumer à une écriture lecture, je vais utiliser les mutex.

    Pour l'instant j'ai simplement créé un mutex nommé qui bloque l'accès à l'une de mes deux applications mais le nombre d'accès est assez inégal entre les deux applications. Je voudrais essayer d'équilibrer le nombre d'écriture/lecture et avoir une vitesse d'exécution la plus rapide possible.

    Le mutex de la table protège "physiquement" en fait l'accès au sous-mutex, qui lui protège "logiquement" les données.
    J'ai du mal a comprendre l'intérêt de poser 2 mutex. Le mutex d'accès aux données défini qui va prendre la main à la prochaine occurrence (écriture ou lecture) et le mutex de table donne l'information qu'une application travaille sur la mémoire partagée?

    Autre point que j'ai oublié de soulever la dernière fois, que doit figurer dans la section critique de la mémoire partagée?

    Je vois les fonctions que je vais utiliser mais pour l'instant j'ai du mal a me faire une idée globale de combiens de mutex je dois créer, combien de threads etc...
    Pour l'intant j'ai ma dll x-plane qui publie mes données sur la mémoire partagée via un thread et mon application test en console qui lance aussi un thread de lecture des données.
    Vous auriez quelques liens vers des cours sur le fonctionnement global et la sécurité?

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par OttisToole Voir le message
    J'aurais besoin de quelques éclaircissements surtout a propos de tes techniques de multithreading Mac Lak
    Pas de soucis.

    Citation Envoyé par OttisToole Voir le message
    J'ai du mal a comprendre l'intérêt de poser 2 mutex. Le mutex d'accès aux données défini qui va prendre la main à la prochaine occurrence (écriture ou lecture) et le mutex de table donne l'information qu'une application travaille sur la mémoire partagée?
    Le mutex "de table" permet en fait de savoir qu'un thread (ou processus) a pris le contrôle de la structure de table. En gros, l'état de la table doit rester figé pendant ce laps de temps. C'est le "vrai" mécanisme de synchronisation, qui interdit aux autres processus / threads de toucher à la table pendant sa mise à jour (ou même simple consultation).

    Le deuxième mutex, le "sous-mutex", n'en est pas forcément un. Cela peut être un sémaphore, un spinlock, un mutex lecteur/rédacteur, n'importe quoi. Ce mutex, dit "logique", permet de savoir ce que l'on FAIT sur la table.
    Est-on en train de la lire simplement ? Si oui, n'importe quel nombre de processus / threads peuvent taper dedans. Est-on en train de la modifier ? Dans ce cas, les "lecteurs" doivent tous arrêter de consulter la table avant que l'on puisse la modifier. Cela dépend intégralement de ton algo et de tes besoins, en fait.

    Citation Envoyé par OttisToole Voir le message
    Autre point que j'ai oublié de soulever la dernière fois, que doit figurer dans la section critique de la mémoire partagée?
    En pratique, quel que soit l'OS, un mutex en mémoire partagée est forcément global pour le système. Donc, même un simple mutex habituellement limité au processus courant devient alors compatible multi-processus (un mutex global au système est souvent implémenté de cette manière d'ailleurs, via un bout de mémoire partagée).
    Dans ton cas, un simple "pthread_mutex_t" suffira amplement, par exemple.

    N'oublie pas qu'il ne faut pas l'initialiser plusieurs fois : seul le thread / processus qui crée la mémoire partagée initialise ce mutex, et seul celui qui détruit la mémoire partagée le libère !!!

    Citation Envoyé par OttisToole Voir le message
    Je vois les fonctions que je vais utiliser mais pour l'instant j'ai du mal a me faire une idée globale de combiens de mutex je dois créer, combien de threads etc...
    Un thread par lecteur, un thread par rédacteur, plus bien sûr un thread "principal" pour chaque processus.
    Côté mutex, on pourrait se débrouiller avec un seul au besoin, mais cela demanderait une structure de table en mémoire partagée un peu complexe pour obtenir des performances correctes.
    J'aurais tendance à dire que si tu penses avoir besoin d'un mutex (c'est à dire qu'il y a risque d'accès concurrent avec conséquences lourdes sur une donnée), alors rajoutes-le, mais ce n'est pas toujours utile ni souhaitable...

    Citation Envoyé par OttisToole Voir le message
    Vous auriez quelques liens vers des cours sur le fonctionnement global et la sécurité?
    N'importe quel tuto de programmation parallèle fera l'affaire, ce sont des principes de base en fait.


    Pour ma part, par rapport à ton besoin, je ferais ça avec une mémoire partagée en trois parties :
    • Un mutex en début de table, avec éventuellement quelques indices min / max sur l'utilisation de la table si c'est nécessaire.
    • Une table d'occupation (entiers), de 0 à (N-1) (N étant la capacité que tu souhaites donner à ta mémoire partagée).
    • Une table de données, de 0 à (N-1) aussi.


    Le mutex protège la table d'occupation, initialisée à "0" sur les N cellules. On se fiche de l'initialisation de la table de données.

    Production d'une donnée :
    • PRISE DU MUTEX DE TABLE.
    • Recherche d'une cellule vide dans la table d'indices (valeur "0", donc), algo à définir en fonction des besoins (FIFO ? LIFO ? aucune importance ?).
    • Mise à "-1" de la cellule correspondante, on retient l'indice noté I ensuite.
    • Éventuellement : Mise à jour des pointeurs de table.
    • LIBÉRATION DU MUTEX DE TABLE.
    • Copie des données dans la table de données, à l'indice I. Cette opération peut être longue.
    • Mise de la valeur "1" dans la cellule de la table d'occupation.
    • Fin de production.


    Consommation d'une donnée :
    • PRISE DU MUTEX DE TABLE.
    • Recherche d'une cellule valant "1" dans la table d'indices (valeur ">0", donc), algo à définir en fonction des besoins (FIFO ? LIFO ? aucune importance ?).
    • Mise à "-1" de la cellule correspondante, on retient l'indice noté I ensuite.
    • Éventuellement : Mise à jour des pointeurs de table.
    • LIBÉRATION DU MUTEX DE TABLE.
    • Copie des données depuis la table de données, à l'indice I. Cette opération peut être longue.
    • Mise de la valeur "0" dans la cellule de la table d'occupation.
    • Fin de consommation.


    La table d'occupation permet de savoir ce que l'on est en train de faire à la cellule correspondante :
    • -1 : Cellule occupée, donnée INVALIDE (modification en cours).
    • 0 : Cellule vide.
    • 1 : Cellule occupée, donnée valide.


    De plus, le mutex de table est alors toujours pris pour des durées très courtes, ce qui ne pose pas de problèmes de performances en général. Si tu utilises un algorithme "strict" quant à la production / consommation (ex : FIFO), alors tu sais toujours à l'avance très exactement quelle cellule lire / écrire, les pointeurs sont idéalement stockés en début de table avec le mutex. Le temps de section critique est alors quasiment négligeable.


    Est-ce un peu plus clair pour toi ?

  11. #11
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    Oui même bien plus clair , je viens de saisir l'intérêt du deuxième mutex. Il te fait gagner de la perfo en fait.

    Quand tu parles de cellules, c'est le nombre d'emplacements de mémoire partagée nommées?
    Par exemple, dans mon cas je dois transférer 4 gros ensembles de données de mon simulateur de vol vers une autre appli. C'est du genre, données générale, données moteurs, données fuel ou encore données navigation.

    Pour l'instant j'avais dans l'idée de faire 1 structure et emplacement de mémoire partagée par ensemble de données.
    Seulement en voyant ce que tu viens de m'expliquer, je me dis que pour un gain de perfo je pourrais faire 2 thread par ensemble de données (lecteur et rédacteur) et 1 emplacement mémoire pour chaque données de l'ensemble (altitude, longitude, alti barométrique etc...).

    Je viens de me dire que c'est pas forcément très malin :p; ca risque de bloquer le mutex en fait, je vais plutôt faire 2 threads (lecteur + rédacteur) pour mes 4 ensembles de données (organisées en 4 structures) et 1 emplacement de mémoire partagée par structure.

    Par contre, n'y aura t-il pas un risque lié a l'accès de la table d'occupation partagée lors de l'avant dernière étape? Ne faut-il par à ce niveau la faire aussi appel au mutex?

    Pour une utilisation équitable entre écriture/lecture, il faut que j'utilise le mutex de table avec les indices (faire une sorte de pile)?

    Ce que tu appel section critique c'est bien entre la prise et la libération du mutex?

  12. #12
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 14
    Points : 10
    Points
    10
    Par défaut
    C'est bon j'ai réussi a faire quelque chose de fonctionnel , merci encore à toi Mac LAK pour tes indications.

  13. #13
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Oups, j'avais zappé ton message du 27/07, désolé...

    Citation Envoyé par OttisToole Voir le message
    merci encore à toi Mac LAK pour tes indications.
    De rien. Un p'tit alors ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Solution de transfert de fichier entre 2 applications sur 2 serveurs différents
    Par garthos dans le forum Développement Web en Java
    Réponses: 5
    Dernier message: 15/04/2013, 14h56
  2. Transfert de donnée entre WP7 et application PC
    Par jerem3000 dans le forum Windows Phone
    Réponses: 19
    Dernier message: 07/03/2011, 19h40
  3. Envoi de message entre 2 applications
    Par floweez dans le forum Windows
    Réponses: 9
    Dernier message: 30/06/2004, 17h34
  4. couche entre partie applicative et donnée
    Par crossbow dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 14/06/2004, 16h54
  5. [Designer] Problème de transfert de données entre modul
    Par BILLYPATOU dans le forum Designer
    Réponses: 11
    Dernier message: 09/03/2004, 19h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo