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 :

Executer une fonction (avec paramètres) dans un thread secondaire


Sujet :

Threads & Processus C++

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut Executer une fonction (avec paramètres) dans un thread secondaire
    Bonjour à tous,

    Je travaille sur une application très complexe. Et j'envisage, pour rendre l'application plus disponible, créer un thread qui me permet d'exécuter une fonction qui a plusieurs paramètres dans un thread secondaire. J'ai commence à regarder comment créer un thread, et j'en ai trouvé plusieurs. Le problème c'est que je suis débutant dans ce domaine et j'ai besoin d'aide.

    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
    int main()
    {
    //plusieurs instructions et appel de fonctions
     
    fonction (a, b, c)
     
    ///////////
    //à ce niveau je veux remplacer la fonction par le lancement d'un thread qui permet d'exécuter la fonction 
    ///////////
     
    }
     
    void fonction (int a, bool b, int c)
    {
    a= 2; 
    c=a+2
    if (c = 4)
    printf(" test ")
    }
    Merci pour vos réponses

  2. #2
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Bonjour.

    Tu as effectivement différentes solutions qui dépendent beaucoups de ce que tu veux faire.

    Pour cela, il faudrait savoir:
    • ta fonction est elle appelée dans une boucle type boucle for ? (si oui, OpenMp est peut être la meilleure solution).
    • Les paramètres de ta fonction sont -ils toujours les même (apres le début du lancement du thread) ou peuvent-ils varier au cours du thread? (s'ils peuvent varier, tu va avoir besoin de mutexes-> Boost thread ou appels systèmes ou autre, (je les connais pas toutes ).Note que si ce sont plusieurs appels de fonction, ce n'est absolument pas nécessaire(il suffit d'avoir un thread par appel)...a moins qu'il y ait des passage par référence).
    • Ta fonction manipule-elle des variables externes (idem, mutexes).
    • Ton application est-elle destinée à être multi-plateforme ?
    • sinon, sur quel système d'exploitation es-tu ?



    Bonne chance

  3. #3
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Merci bcp pour ta réponse.
    • Ma fonction n'est pas appelé en boucle.
    • Les paramètres de ma fonction sont tjs les mêmes
    • Ma fonction ne manipule pas des variables externes
    • Ma fonction n'est pas destinée à être multi-plateforme
    • Mon application tourne sur un système d'exploitation windows et le développement est sous Visual Studio C++ 6.0


    Avant de poster ce sujet, j'ai regardé un peu sur le net. Et j'ai commencé par utiliser _beginthread. Le problème c'est qu'elle permet de lancer une fonction sans paramètres. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    main()
    {
    int n = 5;
    _beginthread(MaFonction,0,(void*)n);
    }
     
    void MaFonction(void*)
    {
     printf("Le nombre : %d",id);
     _endthread();
    }
    Mais avec une fonction avec 2 ou 3 paramètre différents je ne sais pas comment faire.

    Je m'excuse d'avance si j'ai du mal à m'exprimer et expliquer mon problème. C'est parce que je ne suis pas un expert dans ce domaine.

    Merci à tous

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    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
    struct funcParams
    {int a; bool b; int c;
    };
     
    fonction (a, b, c);
     
    main()
    {
      funcParams params;
      params.a = 1;
      params.b = true;
      params.c = 42;
    _beginthread(MaFonction,0,&params);
    }
     
    void MaFonction(void* p)
    {
      funcParams *params = static_cast<funcParams>(p);
      f(params->a, params->b, params->c);
    }

  5. #5
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par you38 Voir le message
    Merci bcp pour ta réponse.
    • Ma fonction n'est pas appelé en boucle.
    • Les paramètres de ma fonction sont tjs les mêmes
    • Ma fonction ne manipule pas des variables externes
    • Ma fonction n'est pas destinée à être multi-plateforme
    • Mon application tourne sur un système d'exploitation windows et le développement est sous Visual Studio C++ 6.0
    En gros, un simple fork suffirait. Par contre, pas de chance de devoir encore être sur VC6.0. C'est imposé par ton patron ?

    Citation Envoyé par you38 Voir le message
    Avant de poster ce sujet, j'ai regardé un peu sur le net. Et j'ai commencé par utiliser _beginthread. Le problème c'est qu'elle permet de lancer une fonction sans paramètres.
    [...]

    Mais avec une fonction avec 2 ou 3 paramètre différents je ne sais pas comment faire.
    Attention à ne pas confondre void* et void: En effet, alors que void est littéralement rien, void* est un pointeur sur rien autrement dit, un pointeur sans type soit un pointeur sur n'importe-quoi en fait (donc potentiellement sur tout, oui, je sais, c'est tordu ).
    Tu transmet donc bien un paramètre à ta fonction. il te suffit de le recaster après pour obtenir ce que tu veux par exemple dans ton cas:

    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
    struct mestroisParamètres
    {
       int Param1;
       bool Param2;
       int Param3;
    };
    main()
    {
       mestroisParamètres mtP = {4,true,54};
       _beginthread(MaFonction,0,(void*)mtP ;
       //Atttention a ne pas modifier mtP avant la fin du thread !
    }
     
    void MaFonction(void* mesParametres)
    {
      if(((mestroisParamètres*)mesParametres)->Param2)
         printf("Le Param1 est : %d Le Param2 est Vrai, Le Param3 est %d",
             &((mestroisParamètres*)mesParametres)->Param1,
             &((mestroisParamètres*)mesParametres)->Param3);
      else
          printf("Le Param1 est : %d Le Param2 est Faux, Le Param3 est %d",
             &((mestroisParamètres*)mesParametres)->Param1,
             &((mestroisParamètres*)mesParametres)->Param3);
       _endthread();
    }
    Normalement, il serait plus à propos d'utiliser cin et cout, mais vu que Vc++6.0 ne respecte pas la norme et est à peine du c++, mieux vaut rester C-style.(par contre, j'ai écris ça à la volée, je ne me rappelle plus si le printf prend des pointeurs ou des valeurs en paramètres donc, à corriger en cas de besoin.)

    Citation Envoyé par you38 Voir le message
    Je m'excuse d'avance si j'ai du mal à m'exprimer et expliquer mon problème. C'est parce que je ne suis pas un expert dans ce domaine.

    Merci à tous
    Au contraire, c'est plutot clair

    Bonne chance pour la suite

    EDIT: arf, grilled par joly_loic. Par contre, tu es sûr que le static_cast est disponible sur VC++6.0 ?

  6. #6
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Merci méphistopheles. Affirmatif, VC6 est imposé

    Merci pour message JolyLoic, et j'ai bien pris connaissance de la notification que tu ma envoyé. Je tiens à m'excuser car je suis un nouveau sur le forum

    J'ai procèdé comme tu viens de le préciser et j'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
    As-tu une idée d'où ça peut venir ?

    Merci

  7. #7
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par you38 Voir le message
    Merci méphistopheles. Affirmatif, VC6 est imposé

    Merci pour message JolyLoic, et j'ai bien pris connaissance de la notification que tu ma envoyé. Je tiens à m'excuser car je suis un nouveau sur le forum

    J'ai procèdé comme tu viens de le préciser et j'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
    As-tu une idée d'où ça peut venir ?

    Merci
    J'ai l'impression qu'il y a confusion avec un pointeur de fonction. faudra que je reregarde la syntaxe du cast (pas le temps là, je fairais un édit ou un autre post). est-ce que ça fait la même chose avec le code de joly_loic ?

    Bonne chance

  8. #8
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Oui affirmatif.

    Je continuerai à creuser et je ferai un poste en fin de journée !

    Merci infiniment

  9. #9
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Je crois que j'ai trouvé en fait, c'est juste qu'il faut donner un pointeur de fonction donc remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       _beginthread(MaFonction,0,(void*)mtP ;
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       _beginthread(&MaFonction,0,(void*)mtP ;
    Bonne chance

  10. #10
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    maintenant j'ai ça comme message d'erreur :
    error C2440: 'type cast' : cannot convert from 'struct mestroisParametres' to 'void *'
    Alors j'ai l'impression qu'il n'arrive pas à caster une structure car une fois je mets autre chose qu'une structure comme magie y a plus de messages d'erreurs. Alors que mon but est de faire passer plusieurs paramètres et non pas un seul.
    Merci

  11. #11
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par you38 Voir le message
    maintenant j'ai ça comme message d'erreur :

    Alors j'ai l'impression qu'il n'arrive pas à caster une structure car une fois je mets autre chose qu'une structure comme magie y a plus de messages d'erreurs. Alors que mon but est de faire passer plusieurs paramètres et non pas un seul.
    Merci
    heu j'ai oublié de déréférencer : il faut remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _beginthread(&MaFonction,0,(void*)mtP ;
    par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _beginthread(&MaFonction,0,(void*)&mtP) ;
    (oui, j'ai aussi remarqué que j'avais oublié la parenthèse).

    Bonne chance

  12. #12
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Merci méphistopheles,

    Ok maintenant ça marche dans ton exemple. Par contre, j'ai fait la même chose dans mon appli et ça pose problème, il me met ce message d'erreur :
    error C2276: '&' : illegal operation on bound member function expression
    J'estime que quelque chose qui ne va pas dans mon code. Je continue à chercher.

    Merci

  13. #13
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par you38 Voir le message
    Merci méphistopheles,
    J'estime que quelque chose qui ne va pas dans mon code. Je continue à chercher.i
    On peut voir ton code ?
    on aura du mal à deviner l'erreur sans .

    Merci.

  14. #14
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Ce code correspond à une fonction qui est appellé lorsque le serveur à fini de transmettre tous les données au poste client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    EndofTransactionS2C()      //Fin de transaction entre le serveur et le client
    {
     Tableau(true,1,true);
     Image(true,1,true);
     Position(x,y,z);
    }
    Chaque de ces fonctions permettent de mettre à jour les données client. Alors mon objectif est de les lancer dans des threads secondaires. Ce que j'ai fait est de remplacer : par
    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
    (dans le fichier.h)
    typedef struct ST{ 
        bool bool1;
        int entier; 
        bool bool2; 
    }thestruct;
    (remplacer directement dans EndofTransaction())
    thestruct st = {true, 1, true};
    _beginthread(&MaFonction,0,(void*)&st);
     
    void MaFonction(void* p)
    {
      thestruct * st = static_cast<thestruct>(p);
      Tableau(st->bool1, st->entier, st->bool2);
      _endthread();
    }
    Si tu veux plus de précision n'hésite pas à me le demander
    Merci

  15. #15
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Il me semble que c'est une erreur de cast :

    il ne faut pas caster en thestruct mais en thestruc* ce qui te fais donc remplacer la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    thestruct * st = static_cast<thestruct>(p);
    par la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    thestruct * st = static_cast<thestruct*>(p);
    À coté de ça, une petite remarque:
    Citation Envoyé par you38 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (dans le fichier.h)
    typedef struct ST{ 
        bool bool1;
        int entier; 
        bool bool2; 
    }thestruct;
    en C++, les typedefs de structs ne sont pas obligatoire: tu peux directement écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct thestruct{ 
        bool bool1;
        int entier; 
        bool bool2; 
    };
    Et le comportement sera le même... sauf que tu aura évité d'encombrer ton espace de nommage d'un nom de plus.

    Bonne chance

  16. #16
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Bonjour,
    J'ai fait les modifications que tu m'as dit et j'ai toujours la même erreur :
    error C2276: '&' : illegal operation on bound member function expression
    Je presente ici un peu plus en détaille le code :
    Le fichier.h
    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
    //La structure pour le passage de paramètres
    struct thestruct{ 
        bool bool1;
        int entier; 
        bool bool2; 
    };
     
    Class Representation
    {
    public :
    //bcp de méthodes dont EndofTransactionS2C et MaFonction
    void EndofTransactionS2C();
    void MaFonction(void* p);
    //Les fonctions de Mise à jour
     Tableau(true,1,true);
     Image(true,1,true);
     Position(x,y,z);
    }
    Le fichier.cpp
    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
    void Representation::Tableau(bool bool1,int entier,bool bool2)
    {
    ///////définition////////
    }
    void Representation::Image(bool bool1,int entier,bool bool2)
    {
    ///////définition////////
    }
    void Representation::Position(int x,int y,int z);
    {
    ///////définition////////
    }
    void Representation::EndofTransactionS2C()      //Fin de transaction entre le serveur et le client
    {
     //Tableau(true,1,true); au lieu  d'appeler la fonction Tableau directement
    //on l'appelle dans un thread secondaire
    thestruct st = {true, -1, true};
    _beginthread(&MaFonction,0,(void*)&st);
     
    Image(true,1,true);
    Position(x,y,z);
    }
    void Representation::MaFonction(void* p)
    {
      thestruct * st = static_cast<thestruct*>(p);
      Tableau(st->bool1, st->entier, st->bool2);
      _endthread();
    }
    J'espère que j'ai pu éclaircir un peu plus le code. Merci

  17. #17
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Salut,

    J'ai trouvé la solution, MaFonction doit être déclarée static pour résoudre le problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static void MaFonction(void* p);
    Malgré ça j'ai d'autres erreurs et problèmes plus liées au code de l'application. Je vous tiendrai au courant dès que j'établis mes problèmes.

    Merci bcp pour ton aide précieux.

  18. #18
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Maintenant j'ai ça comme erreur :
    error C2352: 'Representation::Tableau' : illegal call of non-static member function
    see declaration of 'Tableau'
    Il est impossible d'appeler un fonction membre d'une classe à partir d'un fonction statique. Le problème c'est que si je modifie cette fonction en fonction statique, il faut que je modifie d'autres fonctions qui sont appelés dans cette fonctions en fonctions statiques et c'est cercle vicieux

    Merci

  19. #19
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    C'est le même principe. Tu ajoutes à la structure contenant les arguments un pointeur sur Representation, que tu initialises avec this dans EndofTransactionS2C, tu rends MaFonction libre (plutôt que statique, formellement, c'est mieux, et il faudrait même qu'elle soit extern "C").

    Et dans MaFonction, tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      thestruct * st = static_cast<thestruct>(p);
      st->object->Tableau(st->bool1, st->entier, st->bool2);

  20. #20
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par you38 Voir le message
    Salut,

    J'ai trouvé la solution, MaFonction doit être déclarée static pour résoudre le problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static void MaFonction(void* p);
    L'autre solution aurait été d'utiliser boost::bind ou boost function.
    En effet, le probleme ici est qu'en réalité, une fonction membre est appelée avec en premier paramètre un pointeur sur la classe maitre... aussi lorsque tu passe un pointeur sur cette fonction, c'est en fait une fonction à deux argument (le premier du type TaClasse *).

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/01/2012, 14h18
  2. Executer une application avec paramètres
    Par GUNNM45 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 17/09/2008, 09h54
  3. appeler une méthode avec paramètre dans une page JSP
    Par javasmif dans le forum Struts 2
    Réponses: 1
    Dernier message: 06/12/2007, 10h48
  4. Réponses: 18
    Dernier message: 27/10/2006, 14h15
  5. Peut-on executer une fonction qui est dans un iframe ??
    Par miloud dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 19/04/2006, 11h52

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