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 :

Héritage, fonction virtuelle, redefinition et thread


Sujet :

Threads & Processus C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut Héritage, fonction virtuelle, redefinition et thread
    Bonjour,

    J'explique mon problème qui est un peu complexe :
    Je crée une classe thread générique qui fonctionne ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Thread
    {
         friend void * _starter(void * data);
         bool		Start();
         virtual void task() ; //tache principale qui doit etre redefinie
    };
     
    class MonThread : public Thread
    {
        virtual void task();
    };
    le constructeur de Thread apelle Start() qui crée le thread avec pthread_create et _starter avec en argument data this

    _starter apelle la fonction task() qui est redéfinie dans ma classe MonThread qui herite de la classe Thread.

    Le probleme c'est que la fonction task apellée dans _starter est celle de la classe Thread et non celle redéfinie dans ma nouvelle classe MonThread.
    J'ai compris que c'est parce que lors de la création de l'objet thread la fonction task redéfinie n'existe pas encore donc il apelle celle de base.
    J'ai trouvé un moyen de contourner le probleme en mettant un sleep(1) juste avant d'apeller task() dans ma classe thread. Du coup il apelle bien la fonction redéfinie.
    Y a t'il un moyen plus propre de faire ca, comme par exemple en attendant la création de l'objet avant d'apeller la fonction autrement que par un sleep ?

    merci

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tu ne devrais juste pas lancer le thread dans son constructeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonThread t; // --> ne fait rien
    t.Start(); // --> appelle pthread_create, _starter et tout le tralala
    PS : autant mettre _starter en static privée dans Thread, elle n'a d'utilité que dans cette classe.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Oui j'y avais pensé, mais j'essayai de pouvoir tout lancer seulement en créant l'objet.

    Quand au static privé, si je le fait alors je n'ai plus accès aux variables privées de ma classe dans starter, et j'en ai besoin (exemple : un booléen running que je met a true dans starter)

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Oui j'y avais pensé, mais j'essayai de pouvoir tout lancer seulement en créant l'objet.
    Bien que ce soit généralement une bonne idée, dans ce cas là c'en est une mauvaise
    Par exemple, comment tu fais si tu as un thread en donnée membre, pour qu'il ne se lance pas dès la construction de l'objet parent ? Ou si tu veux démarrer le thread dans une portée plus courte que la durée de vie souhaitée du thread (par exemple un bloc if) ? Ce que tu veux faire est une contrainte beaucoup trop pénalisante.
    Si tu n'es toujours pas convaincu jette un oeil à toutes les bibliothèques qui fournissent une telle classe : le lancement du thread est toujours séparé de sa construction.

    Quand au static privé, si je le fait alors je n'ai plus accès aux variables privées de ma classe dans starter, et j'en ai besoin (exemple : un booléen running que je met a true dans starter)
    Justement si, puisque _starter sera alors membre de Thread.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Tu m'as convaincu :p

    Par contre :
    Citation Envoyé par Laurent Gomila Voir le message
    Justement si, puisque _starter sera alors membre de Thread.
    Thread.cpp:18: error: cannot declare member function ‘static void* Thread::_starter(void*)’ to have static linkage

  6. #6
    Membre averti

    Inscrit en
    Juillet 2008
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 186
    Points : 350
    Points
    350
    Par défaut
    A noter une implémentation un peu différente qui diminue le couplage entre l'objet de thread et l'execution qui est faite. Il faut avoir une classe d'interface threadable, dont on définit une classe personalisée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class threadable {
    public:
        virtual void execute(void *data) = 0;
    };
     
    class mon_threadable {
    public:
        virtual void execute(void *data);
    };
    Et puis on définit une classe qui execute ces objets threadable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class threader {
    public:
        void start(threadable *thread);
    };
    C'est cette fonction threader qui gère et donc crée les threads en appelant thread_create. Et c'est lors de l'appel de threader.start() que la fonction membre threadable.execute() est appelée dans un autre thread d'exécution.

    A noter que cela offre l'avantage de pouvoir implémenter le threader différemment selon ses besoins. On peut ainsi utiliser un pool de thread pour les réutiliser et ne pas en créer un nouveau à chaque fois qu'il faut exécuter un nouveau threadable.

    Enfin, l'implémentation du threader est complètement séparée du threadable. Aussi, la durée de vie des objets de threadable et threader peuvent être différente. Tout ceci diminue le couplage.

  7. #7
    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
    Dans ce cas là, autant utiliser boost::function, c'est encore plus flexible.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour l'erreur avec static, il ne faut pas répéter le mot "static" dans le .cpp.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Ha oui ça marche mieux

    Merci pour les conseils.

    et merci aussi à dtrosset pour l'idée ça permet de voir une autre possibilité.

    Car je n'ai pas rouvé beaucoup d'exemples de classes de thread en C++, et les quelques que j'ai trouvées contiennent souvent pas mal d'erreurs.
    Celle dont j'ai pris exemple est ici, pour info :
    http://www.codeguru.com/cpp/cpp/cpp_...php/c14447__5/

    Je fait ceci car j'ai besoin d'une classe générique pour créer facilement des classes "threadés" sans librairies tierces.

  10. #10
    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
    As-tu regardé boost::thread ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Oui, mais comme je disais juste au dessus :
    Je fait ceci car j'ai besoin d'une classe générique pour créer facilement des classes "threadés" sans librairies tierces.

  12. #12
    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
    Ce n'est pas possible. Le C++ ne possède pas la notion de thread, tu es obligé de passer par une bibliothèque tierce pour en créer. Et tant qu'à faire, autant utiliser boost::thread, qui est de bonne qualité, portable, et proche de ce que seront les threads gérées directement en C++ le jour où elles existeront.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    screetch
    Invité(e)
    Par défaut
    entre une dependance sur boost et une dependance sur pthread, il y a un pas que je n'ai jamais reussi a franchir. boost tire la moitié du monde avec lui...

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

Discussions similaires

  1. Héritage multiple et fonction virtuelle
    Par chronos dans le forum C++/CLI
    Réponses: 0
    Dernier message: 14/02/2012, 09h59
  2. Héritage et fonction virtuelle
    Par gzeus dans le forum C++
    Réponses: 5
    Dernier message: 05/07/2008, 00h42
  3. Réponses: 8
    Dernier message: 18/06/2007, 15h06
  4. Réponses: 16
    Dernier message: 21/05/2007, 01h04
  5. [POO] Héritage, fonctions virtuelles
    Par mamid1706 dans le forum C++
    Réponses: 8
    Dernier message: 09/05/2007, 11h43

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