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 :

[MT] Existence d'un thread


Sujet :

Threads & Processus C++

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut [MT] Existence d'un thread
    Bonjour,

    Je me demandais s'il existait une méthode ou bien une astuce pour tester l'existence d'un thread, cad si le processus est en train de tourner ?

    J'ai parcouru la msdn et google, rien trouvé qui puisse me servir.

    Mon programme fait appel à des threads, seulement j'aimerai qu'il en lance un seul à la fois, donc lorsque le deuxieme se lance, il faudrait tuer le premier avant. Ce que je fais actuellement.
    Seulement lorsqu'il n'y a pas de processus en cours et que je tente de killer, le programme plante, normal.

    Une suggestion pour pallier au probleme ?
    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 utilises quelle bibliothèque de threads ?

  3. #3
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Pourquoi "tuer" un thread? C'est un peu violent non?
    Il vaut mieux utiliser les mutex si tu veux synchroniser des thread.

    Au passage, j'avais déjà posé ce genre de question, et apparemment il n'y a que les thread windows que tu peux "killer". Pas de boost, ni de pthread.
    D'où la question de Laurent je pense.

  4. #4
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    J'utilise la classe CWinThread et la fonction AfxBeginThread, standard MFC me semble-t-il.
    Il s'agirait donc bien des thread windows, ca me laisse un petit espoir.

    @poukill : je n'ai aucun besoin de synchroniser mes threads.
    Voici le contexte : j'ai une fenetre qui contient une liste contenant des noms d'images. Lorsque l'utilisateur clique sur une entrée, un thread se lance et affiche un thumbnail de l'image. J'utilise des threads sinon l'appli se bloque pendant le calcul du thumbnail, ce qui n'est pas "user friendly", pour citer mon patron.
    Ainsi, lorsque l'utilisateur clique sur une entrée, puis sur une autre, il faut que le thumb correspondant a la deuxieme entrée s'affiche, plus besoin de calculer le thumb correspondant a la premiere entrée. On peut donc tuer ce thread. C'est meme nécessaire, car si un thread est plus rapide qu'un autre (taille des images), le thumb correspondant a l'image cliquée en premier peut apparaitre en deuxieme. Bref, cela genere des incohérences.

    Je suis preneur pour toute idée, meme s'il faut changer de direction.

  5. #5
    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
    Tuer un thread n'est jamais conseillé, d'ailleurs ce n'est pas pour rien que les APIs un peu haut niveau n'intègrent pas cette fonction.

    La fonction qui calcule/affiche ton image doit être sous forme de boucle, non ? Si c'est le cas alors il vaut mieux tester une condition à chaque tour de boucle (un simple booléen peut faire l'affaire), et lorsque le thread principal rend cette condition fausse, le thread secondaire sait qu'il doit s'arrêter de boucler. C'est propre et ça permet de libérer correctement les ressources du thread.

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Comme te l'a dit Laurent, il convient de demander a un thread de s'arreter de lui meme, et non de l'assassiner. Ca peut te causer des problemes, liés a des ressources allouées non libérées (parce que tué).
    Au lieu de le tuer pour en créer un nouveau, pourquoi ne pas envisager de le réutiliser, de le réinitialiser en quelque sorte ? "Arrete ton calcul en cours et recommence avec ce thumbnail".

  7. #7
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    En général, une classe de thread contient un "signal" d'interruption qui peut être testé regulièrement... pendant le calcul du thumbnail...

    Si ce n'est pas le cas, l'implémentation est simple:
    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
     
    class ThumbnailCreationThread : public MaClassDeThread
    {
          MaClasseDeSignal    mSignal;
     
    public:
        ThumbnailCreationThread()
        {
            mSignal.init(); // <= initialisation avec le signal non levé..
        }
     
        ~ThumbnailCreationThread()
        {
            mSignal.dispose();
        }
     
     
        void   Start()
        {
            if (!isRunning()) {
                mSignal.reset();
                MaClasseDeThread::Start();
            }
        }
     
        void   Stop()
        {
            if (isRunning()) {
                mSignal.set();
                MaClassDeThread::Stop(); // <= si existe
            }
        }
     
        void   Run()
        {
            // on teste régulièrement le signal...
            for ( ... ;  && !mSignal.isSet(); ) {
     
            }
     
            // on remplace sleep(n) par 
            if (mSignal.wait(500)) return; 
        }
    };
    Maintenant, tout dépend du contexte... Dans une application de gestion d'images ou de nombreuses opérations sont "longues", il vaut mieux implémenter un système de thread-pool et de "tâches" à effectuer....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  8. #8
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Laurent, non ma fonction thread n'est pas sous forme de boucle. Je lance le thread lors d'un clique, celui-ci calcule le thumb et l'affiche, puis se termine. D'ailleurs, je ne vois pas trop comment coder ça sous forme de boucle. Cela reviendrai a avoir ce thread qui tourne en continu, consommant donc des ressources inutilement puisque le besoin de calculer un thumb est occasionnel.

    Aurelien, ce dont tu parles dans ta réponse est exactement ce que j'avais envie de faire ! Lors d'un second clique, j'aimerai
    -vérifier si un "Thread Thumb" existe deja
    -si non, on en lance un normalement
    -si oui, on le réinitialise, et le relance pour calculer le thread correspondant au deuxieme clique.
    Malheureusement, je n'ai pas trouvé de fonction pour tester l'existence d'un tel thread. D'ou le titre de mon post !

    Et effectivement, si je ne trouve vraiment rien d'ici les prochains jours, je vais essayer de me débrouiller avec des messages, comme me le conseille nicroman.

    Merci les gars.

  9. #9
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    En fait il y a forcément une boucle dans ton calcul, mais peut etre qu'elle est dans une fonction que tu appelles et dont tu n'as pas le controle ?

    A partir du moment ou c'est toi qui crée le thread, tu devrais en obtenir un identifiant qui te permet de tester son état (en exécution/terminé). L'autre moyen est que ta procédure de thread signale de lui meme qu'il s'est terminé, mais d'un point de vue design c'est moins élégant (s'il se fait tuer/se plante, il ne signalera pas sa fin d'exécution et ton code continuera de croire qu'il bosse...).

    Faut donner plus de précisions sur ton "calcul de Thumb".

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Oui en fait j'utilise une librairie pour générer le thumbnail, donc effectivement je ne sais pas trop ce qui s'y passe.

    AfxBeginThread() renvoie un CWinThread*.
    Toutefois, en regardant sur la msdn, je n'ai trouvé aucune fonction pour tester son état !

    Et oui, tu viens de me donner une idée !
    En se lançant, le thread change la variable isThread en true, et en se terminant la remet à false.
    Ainsi le prog principal sait si un thread est actuellement en train de tourner, et si c'est le cas on peut le descendre avec TerminateProcess.
    Par contre je suis d'accord avec toi, ce n'est pas très élégant...

  11. #11
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Tiens étonnant...
    Ca ne plante plus, mais j'ai toujours les incohérences.. Ce qui veut dire que les threads ne sont pas tués !

    Raaaahhhh, l'informatique..

  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
    Remarques en vrac :

    J'ai l'impression que tu confonds process et thread, ce sont deux choses différentes.

    Pour attendre la fin d'un thread, sous windows, on fait WaitFor[Single/Multiple]Object avec en paramètre le handle du thread. Je ne connais pas les CWinThread, mais il doit y avoir moyen de récupérer un handle à partir de ça. Ou alors, utiliser directement une fonction qui en retourne un, genre _beginthread (vu le niveau d'encapsulation généralement fourni par les MFC, s'en passer n'est pas forcément un problème...).

    Si tu communique entre tes threads par des simples variables, comme ton isThread, sans les protéger, pas étonnant que tu aies des problèmes.
    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
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Un thread = Un process non ? Je fais peut-être l'amalgamme dans mes posts, toutefois je crois avoir compris le fonctionnement. Le fait de lancer des threads permet simplement d'avoir plusieurs process qui s'executent en parallèle.
    Effectivement, il est aisé d'obtenir le handle sur l'objet CWinThread avec myThread->operator HANDLE( ).

    Je ne veux pas attendre la fin du thread avant de lancer le suivant, car celà fait perdre trop de temps ! Je pourrai alors aussi bien coder sans les threads.

    Bon ma solution est à côté de la plaque, car avec Terminate Thread les ressources du thread ne sont pas désallouées.

    J'ai ensuite voulu tenter la solution proposée par nicroman, à savoir communiquer entre mon process principal et mon thread avec un signal, mais je n'ai pas trouvé de classe signal ! C'est peut-être aussi possible avec des messages ?

  14. #14
    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
    Un thread = Un process non ? Je fais peut-être l'amalgamme dans mes posts, toutefois je crois avoir compris le fonctionnement. Le fait de lancer des threads permet simplement d'avoir plusieurs process qui s'executent en parallèle.
    Un processus est assez lourd à créer / exécuter, c'est pour ça qu'on été créés les threads, aussi appelés processus légers. Un processus pourra contenir plusieurs threads, et tous ces threads partageront l'espace mémoire de ce processus (c'est pour cela que c'est plus léger).
    C'est donc bien différent.

  15. #15
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Pour tester si un thread est encore vivant, tu peux:
    - faire un WaitForSingleObject avec un timeout tres faible -> si timeout, le thread est vivant
    - appeler GetExitCodeThread, s'il vaut STILL_ACTIVE et que ton thread ne retourne jamais cette valeur, alors il tourne toujours

    TerminateProcess sur le handle d'un thread ne fera rien -> TerminateThread. Les threads d'un meme process partagent presque tout, c'est pour ca qu'un thread peut facilement en faire planter d'autres / causer des problemes aux autres.

    Peux-tu modifier la bibliotheque que tu utilises ?

  16. #16
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Ok merci pour la précision concernant les threads. Effectivement j'étais dans le flou.

    Ensuite, en ce qui concerne les fonctions WaitForSingleObject et GetExitCodeThread, je ne peux pas les utiliser car quand je les appelle et que le thread n'est pas lancé, elles font planter le programme. Sans doute parce que j'appelle le handle avec myThread->operator HANDLE( ) et que celui-ci n'existe pas !
    Par contre, en utilisant une variable booléenne isThread et TerminateThread, j'ai l'impression que ca fonctionne normalement après quelques tests.
    A voir...

    En tout cas, merci bien pour votre aide.

    edit : et oui, je peux modifier la bibliothèque, je dispose du code source.

  17. #17
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Ah oui mais les ressources ne sont pas libérées.
    Retour au point de départ.

    ---> messages

    J'ai déjà essayé un peu d'implémenter cette solution, je n'ai pas réussi pour l'instant.
    nicroman, si tu es encore là, pourrais tu me dire ce qu'il est possible d'utiliser comme classe de message ? Je n'en ai pas trouvé.
    Aussi, il me semblait que les messages servaient à informer des fenetres. Or mon thread ne dispose d'aucune fenêtre. Puis-je quand meme lui envoyer des messages ?

  18. #18
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par MarronSuisse Voir le message
    Ensuite, en ce qui concerne les fonctions WaitForSingleObject et GetExitCodeThread, je ne peux pas les utiliser car quand je les appelle et que le thread n'est pas lancé, elles font planter le programme.
    Ces fonctions sont hors de cause. D'apres ce que tu dis, ca plante dans ton code parce que myThread est null, tout simplement.

  19. #19
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    Ces fonctions sont hors de cause. D'apres ce que tu dis, ca plante dans ton code parce que myThread est null, tout simplement.

    Oui exactement.

  20. #20
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 52
    Points
    52
    Par défaut
    Bon j'ai maintenant commencer à bosser avec les handlers, en m'aidant du tutoriel : http://cpp.developpez.com/faq/vc/?pa...keWorkerThread section "Comment arrêter un thread de travail ?"
    ainsi que de la discussion : http://developpez.net/forums/showthread.php?t=390750

    Toutefois, c'est toujours pas gagné.

    Il y a des choses bizarres dans ce tutoriel.
    Premièrement, à quoi servent les deux attributs privés m_hEndThread et m_hWaitThread qui ne sont jamais utilisés dans le code ?
    Aussi, je me demandais, de quelle classe doit-on faire dériver la classe CWorkerThread ?

    J'ai implémenté l'exemple sans utiliser les attributs m_hEndThread et m_hWaitThread et sans faire dériver la classe CWorkerThread, et pour l'instant je ne remplis jamais la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(::WaitForSingleObject(param->m_EndThread, 0) == WAIT_OBJECT_0)
    Pourtant, dans mon programme principal, j'appelle tout d'abord le constructeur de CWorkerThread, puis le destructeur qui fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ::SetEvent(m_EndThread);

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/08/2010, 16h35
  2. tester l'existence d'une thread
    Par jhanos dans le forum POSIX
    Réponses: 5
    Dernier message: 16/09/2009, 12h49
  3. Teste si un thread existe déjà.
    Par ouranos21 dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 15/01/2008, 14h41
  4. Réponses: 4
    Dernier message: 12/11/2005, 14h02

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