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

C++ Discussion :

Communication inter-threads: methode elegante?


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Décembre 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 55
    Par défaut Communication inter-threads: methode elegante?
    Bonjour!

    Je me permet de poster une question qui me pourri l'esprit depuis longtemps.
    J'ai mis le code en annexe.

    Mon probleme:
    J'ai cree une classe de "communication" interprocessus afin de regrouper et de simplifier les problemes de mutex et de stocker la variable partagee.
    Dans mes threads, je desire utiliser cette classe de communication. Je n'ai pas trouve d'autre solution que de faire passer un pointeur de l'instance de ma classe communication via l'argument de creation de thread.

    Y aurait-il une solution plus elegante? Je ne desire pas creer de variable globale de l'instance de ma classe de communication.

    J'avais pense mettre la variable partagee de ma classe communication en statique, et creer une nouvelle classe (qui heriterait de cette classe communication) et qui gererait les threads. Mais ca me semble plus lourd.

    Qu'en pensez-vous?

    Merci pour vos reponses :-)

    JC


    classe de communication
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    #include <pthread.h>
     
    class comu
    {
    public:
      comu();
      ~comu(){};
      void add_value (int val);
      int retrieve_value();
     
    private:
      int v;
      pthread_mutex_t mutex;
    };
     
    comu::comu()
    {
      v=0;
      pthread_mutex_init(&mutex,NULL);
    }
     
    void 
    comu::add_value(int val)
    {
      pthread_mutex_lock(&mutex);
      v+=val;
      pthread_mutex_unlock(&mutex);
    }
     
    int
    comu::retrieve_value()
    {
      int val;
      pthread_mutex_lock(&mutex);
      val=v;
      pthread_mutex_unlock(&mutex);
      return val;
    }

    main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    #include <iostream>
    #include "comu.cpp"
     
    int val1=3;
    int val2=6;
     
    void * func1 (void * dummy)
    {
      while(true)
        {
          comu * c=(comu *) dummy;
          std::cout << "Thread 1 adds 3 to the value" << std::endl;
          c->add_value(3);
          sleep (2);
          val1--;
          if (val1==0)
    	{
    	  std::cout<<"Thread 1 exit!"<<std::endl;
    	  pthread_exit(NULL);
    	}
        }
    }
     
    void * func2 (void * dummy)
    {
      while(true)
        {
          comu * c=(comu *) dummy;
          std::cout<<"Thread 2 reads the value: "<< c->retrieve_value()<< std::endl;
          sleep(1);
          val2--;
          if (val2==0)
    	{
    	  std::cout<<"Thread 2 exit!"<<std::endl;
    	  pthread_exit(NULL);
    	}
        }
    }
     
     
     
    int main()
    {
      comu * pcomu=new(comu);
     
      std::cout<<"Init value="<<pcomu->retrieve_value()<<std::endl;
     
      pthread_t t1,t2;
      pthread_create(&t1,NULL,func1,(void *)pcomu);
      pthread_create(&t2,NULL,func2,(void *)pcomu);
     
      pthread_join(t1,NULL);
      pthread_join(t2,NULL);
     
      std::cout<<"Final value="<<pcomu->retrieve_value()<<std::endl;
     
      delete (pcomu);
      return 0;
    }

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    le passage d un pointeur sur l instance n'est pas une mauvaise idée. je trouve que cette solution est simple et fonctionellle. A mon avis elle convient tres bien a tes besoins.

    PS: pense a bien nommer tes classes, variables et objets par des noms qui represente le contenu des informations de manière specialisée.

  3. #3
    Membre averti
    Inscrit en
    Décembre 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 55
    Par défaut
    Ok merci pour l'avis

    A++
    JC

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pourquoi ne pas communiquer via une queue lock-free plutôt ?
    Et si tu préfères utiliser un unique entier, inutile aussi d'utiliser un mutex. Toutes les plate-formes ont des read/write atomiques sur les entiers de la taille d'un mot.

  5. #5
    Membre averti
    Inscrit en
    Décembre 2002
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 55
    Par défaut
    Hello!

    Merci pour vos remarques... Le code que j'avais inséré n'est qu'un exemple du principe que je désire utiliser dans mon projet. (Je n'ai pas un entier comme variable partagée mais une liste de type complexes (classes)) Je n'estime pas non plus avoir a implementer un lock-free. Le systeme de Mutex (dans mon cas) est largement suffisant et efficace.
    Par contre, pour info, un de mes collegues ne jure que par les patterns "singletons" et me dit que pour ma classe de communication ce serait bien. Je suis assez septique (je considere un peu les singletons comme des variables globales améliorées )

    Bref, encore merci

    A++
    JC

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Si ça te fait plaisir de ralentir ton truc pour rien...

  7. #7
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par jc_isd
    Par contre, pour info, un de mes collegues ne jure que par les patterns "singletons" et me dit que pour ma classe de communication ce serait bien. Je suis assez septique (je considere un peu les singletons comme des variables globales améliorées )
    Les singletons c'est le mal !

    Parfois c'est pratique, mais en on finit toujours par se mordre les doigts de les avoir utilisé.
    A mon avis, quand on implémente un singleton on devrait toujours :
    - l'implémenter en dehors de la classe, afin de pouvoir le supprimer si le besoin est... quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class MaClasse_Core{...}
    typedef Singleton<MaClasse_Core> MaClasse;
    Comme ça, le jour où ça va mal, on peut se contenter de changer le typedef.
    - se poser la question : "quelle évolution de code fera tôt ou tard que j'ai besoin de deux instances de ce singleton ?". Il suffit souvent de se poser cette question pour en trouver une.

    Dans ton cas, en particulier, il est évident que tu ne veux pas un singleton au cas où tu aie besoin de faire des communication entre plus de 2 threads. Autrement dit, il n'y a pas de raison que l'objet de communication entre ton thread A et ton thread B soit le même que celui entre le thread B et le thread C. On doit même pouvoir, en cherchant un peu, trouver des cas de dead-lock.

    Note : +1 pour loufoque quand il dit qu'il existe des objets de communication lock-free (c'est à dire qu'on n'est pas obligé de les locker pour lire ou écrire dedans). C'est même assez facile à faire toi-même si tu ne peux pas te permettre d'inclure des librairies existantes. Par contre elles imposent des conditions souvent plus strictes (comme le fait qu'il n'y ai qu'un seul thread lecteur).

    [EDIT]Note pour moi-même : c'est ptet pas utile de répondre à des sujets résolus et en proposition de délestage.[/EDIT]

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Note : +1 pour loufoque quand il dit qu'il existe des objets de communication lock-free (c'est à dire qu'on n'est pas obligé de les locker pour lire ou écrire dedans). C'est même assez facile à faire toi-même si tu ne peux pas te permettre d'inclure des librairies existantes. Par contre elles imposent des conditions souvent plus strictes (comme le fait qu'il n'y ai qu'un seul thread lecteur).
    Le single-reader/single-writer ça date un peu.
    Il y a des algorithmes pour avoir une queue multi-reader/multi-writer en lock-free.

    Mais bon c'est vrai que dans l'absence de bibliothèque portable qui fournit ce genre de choses, c'est pas pratique à utiliser.

  9. #9
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par loufoque
    Le single-reader/single-writer ça date un peu.
    Il y a des algorithmes pour avoir une queue multi-reader/multi-writer en lock-free.
    Pouf pouf, tu fais bien de me corriger, il fallait donc lire :
    "Même si tu ne peux pas inclure de librairie externe, des système de communication lock-free en multi-writer/single-reader, c'est assez facile à coder"
    Cela dit loufoque, si tu sais coder des objets de communication lock-free en multiple-reader/multiple-writer, ça m'intéresse. Peut-être pas pour les recoder moi-même, mais pour savoir comment faire.

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Voir les algorithmes de John D. Valois améliorés par Maged M. Michael.

  11. #11
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    euh ....
    merci

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

Discussions similaires

  1. communication inter threads
    Par contremaitre dans le forum C
    Réponses: 8
    Dernier message: 20/11/2008, 10h48
  2. Communication inter-threads par stdout sous linux
    Par millerf dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 17/07/2007, 11h28
  3. Réponses: 4
    Dernier message: 15/06/2007, 10h41
  4. [c#]Communication inter thread
    Par chasse dans le forum Windows Forms
    Réponses: 6
    Dernier message: 18/12/2006, 20h45
  5. communication inter-thread en c sous linux
    Par splinternabs dans le forum POSIX
    Réponses: 17
    Dernier message: 22/02/2006, 09h34

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