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

Windows Discussion :

Attendre la fin des threads fils d'un processus


Sujet :

Windows

  1. #1
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut Attendre la fin des threads fils d'un processus
    Bonjour,
    Dans un programme, je créer plusieurs threads et j'aurais besoin d'attendre la fin des threads que j'ai crées avant de terminer le processus. Y'a t-il une API pour cela ou faut il le faire soit même. Dans ce cas, il y a plusieurs solutions :
    1. Stocker les handles des threads actifs dans une liste chainée
    2. Faire un compteur avec sémaphore
    3. Une variante du 2 : Déclencher une évènement quand le nombre de threads est à 0 (protection du compteur avec un mutex).

    J'aimerais également pouvoir arrêter tous mes threads. J'ai juste à envoyer un évènement ? Faut il le retransmettre une fois qu'il a été "capté" par un thread afin que les autres threads puissent églament être avertis ?

    J'attends vos avis
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  2. #2
    Membre averti Avatar de Jean-Philippe Shields
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    278
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2005
    Messages : 278
    Points : 340
    Points
    340
    Par défaut
    Salut,

    Je ne suis pas un pro du sujet, mais j'ai déjà personnellement utilisé une librairie open-source qui fait tout ce que tu demandes. Le framework open-source se nomme ACE et est développé par plusieurs universités :

    http://www.cs.wustl.edu/~schmidt/ACE.html

    Le framework inclus des patterns pour utiliser des objects concurrents et donne plusieurs outils de synchronisation, comme ce que tu mentionnes.

    Pour répondre à ta question, personnellement j'utiliserais une variable conditionnelle (sémaphore) dans le thread principal pour attendre la fin de tous les threads lancés. Sur windows l'utilisation de waitForMultipleObjects() seraient approprié, selon mes connaissances.
    RCP rulez!

  3. #3
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    J'ai fait une petite classe perso avec un compteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class GestionThreadsWin
    {
    private:
    	HANDLE hMutex;
    	int cpt;
    
    public:
    	GestionThreadsWin();
    
    	bool WriteCpt(int nb);
    
    	int ReadCpt();
    };
    Je suis quand même étonné. La librairie multitâche offerte par Windows me semble assez pauvre à côté de celles fournies par VxWorks ou Linux. Enfin les principes de bases sont là, donc on peut refaire ce qu'on veut...
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ai du mal à comprendre ce que tu veux.

    Si tu veux que le process ne s'arrête quand TOUS ses threads sont terminés (au lieu du thread du main()/WinMain()), il suffit de remplaçer le return du main()/WinMain() par un appel à ExitThread() : Ainsi, seul ce thread se terminera, au lieu de terminer tout le processus.

    Citation Envoyé par http://msdn.microsoft.com/library/en-us/dllproc/base/terminating_a_process.asp
    The primary thread can avoid terminating other threads by directing them to call ExitThread before causing the process to terminate (for more information, see Terminating a Thread). The primary thread can still call ExitProcess afterwards to ensure that all threads are terminated.
    Si ce n'est pas ce que tu cherches, prière d'être plus explicite.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Je ne sais pas si tu connais la fonction wait(0) sous unix/linux. C'est exactement ce que je veux : c'est à dire que je veux terminer mon processus après la mort de tous les processus fils (threads) qu'il a crée précédemment.

    Si j'utilise l'exit thread, mon processus se termine. Hors je veux qu'il attende.

    Est ce plus clair ?
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    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 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par SteelBox
    Je ne sais pas si tu connais la fonction wait(0) sous unix/linux. C'est exactement ce que je veux : c'est à dire que je veux terminer mon processus après la mort de tous les processus fils (threads) qu'il a crée précédemment.
    ton processus se termine tout seul quand son dernier thread meurt.

  7. #7
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    ton processus se termine tout seul quand son dernier thread meurt.
    J'ai testé et ce n'est pas ce qui se passe. Le processus exécute bien le exit et il n'attend pas la mort de ces threads.
    Process Explorer de Sysinternals liste les threads d'un processus. J'aurais besoin de récupérer ces informations également. Savez vous comment faire ? y'a t-il une API ? il est possible que sysinternals ait été chercher eux même l'information en mémoire...
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    1°) Tu peux nous montrer la fin de ton main() ou WinMain() ?
    2°) On parle bien de threads ou de processus, là? Tu sembles mélanger les deux termes...
    je veux terminer mon processus après la mort de tous les processus fils (threads)...
    Edit: Citation à l'appui...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Je ne pense pas mélanger les termes. Relis bien ce que j'ai écrit et dis moi ou tu penses que je mélange.
    Thread=processus léger. Il possède une desciption réduite et appartient à un processus ce qui fait que le changement de contexte est plus rapide avec un thread.

    Et je n'ai pas de main, c'est une dll.

    En gros, voici ce que je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    				threadID=CreateThread(	NULL	,	// Attributs de sécurité (par défaut)
    					0								,	// Taille de la pile (par défaut)
    					(LPTHREAD_START_ROUTINE)&ExecuteThread	,	// Adresse de la threadproc
    					(LPVOID)this						,	// Paramètres (pointeur this)
    					0								,	// Flag de création (0 ou CREATE_SUSPENDED)
    					0								);	// Pointeur vers le ThreadID (aucun)
    
    ...
    
    sysGtw.WriteCpt(1);
    A la destruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sysGtw.WriteCpt(-1);
    Mon WriteCpt émet un évènement pour me prévenir quand tous les threads que j'ai crées sont morts :
    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
    bool GestionThreadsWin::WriteCpt(int nb)
    { 
        DWORD dwWaitResult;
    
        // Request ownership of mutex.
     
        dwWaitResult = WaitForSingleObject( 
            hMutex,   // handle to mutex
            5000L);   // five-second time-out interval
     
        switch (dwWaitResult) 
        {
            // The thread got mutex ownership.
            case WAIT_OBJECT_0: 
                __try { 
                    // Writing and testing
    					cpt+=nb;
    
    					if(cpt==0)
    					{
    						SetEvent(hStopEvent); // there is no running threads
    					}
    
                }
                __finally { 
                    // Release ownership of the mutex object.
                    if (! ReleaseMutex(hMutex)) 
                    { 
                        // Deal with error.
                    } 
    
                    break; 
                } 
    
            // Cannot get mutex ownership due to time-out.
            case WAIT_TIMEOUT: 
                return false; 
    
            // Got ownership of the abandoned mutex object.
            case WAIT_ABANDONED: 
                return false; 
        }
    
        return true;
    }
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    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 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    Si c'est toi qui crée les thread, dans le thread principal, pourquoi n'en gardes-tu pas trace ?
    Un WaitForMultipleObjects sur les handle des threads créés avec bWaitAll = TRUE fera l'affaire ensuite.

  11. #11
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    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 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par SteelBox
    ton processus se termine tout seul quand son dernier thread meurt.
    J'ai testé et ce n'est pas ce qui se passe.
    je viens de tester sous XP:
    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
    #include <windows.h>
    
    DWORD WINAPI ThreadProc&#40; LPVOID  &#41;
    &#123;
        Sleep&#40; 3000 &#41;;
        MessageBox&#40; 0, TEXT&#40; "Ca va couper!" &#41;, TEXT&#40; "" &#41;, 0 &#41;;
        return 0;
    &#125;
    
    int main&#40;&#41;
    &#123;
        CloseHandle&#40;
            CreateThread&#40; NULL, 0, ThreadProc, 0, 0, NULL &#41; &#41;;
        ExitThread&#40; 0 &#41;;
    &#125;
    j'ai bien le messagebox qui s'affiche.

  12. #12
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Oui, j'avais pensé à cette solution, mais je pensais que Windows devait justement garder cette trace (enfin il l'a garde surement mais il n'offre pas la possibilité d'y avoir accès avec une API). Sinon, je pensais faire une liste chainée des threads mais pour l'instant, le fait de les compter me suffit. Si j'ai besoin de les stopper ou les mettre en pause, j'adopterai la solution de la liste chainée.

    Bref, je pensais que l'API Windows était plus fournie que ca. Vous avourez qu'il s'avère étonnant qu'aucune API ne permette d'attendre la fin des threads crées par notre processus.

    Merci pour votre aide, j'ai eu les réponses que j'attendaient
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  13. #13
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    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 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par SteelBox
    Bref, je pensais que l'API Windows était plus fournie que ca. Vous avourez qu'il s'avère étonnant qu'aucune API ne permette d'attendre la fin des threads crées par notre processus.
    Mais ça n'a pas de sens. Si dans ton thread principal tu attends que tous les thread du processus soient terminés, vu que le thread principal est avant tout un thread du processus comme un autre, il va attendre sa propre fin, autrement dit, il va attendre indéfiniment.
    Après on peut lister les thread d'un process en Win32, mais vu que c'est ton propre process, ça semble plus normal et surtout c'est plus simple de garder une trace de ce que tu crées.

  14. #14
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    C'est vrai que la fonction wait de Linux mentionne les "processus fils". Il y a donc une petite distinction avec Windows. Néamoins cette fonction est réelement très utile :
    http://www.die.net/doc/linux/man/man2/wait.2.html

    -1 which means to wait for any child process;
    Concernant le CloseHandle, ca semble marcher effectivement (ce n'est pourtant pas vraiment explicité dans la MSDN). Merci
    Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.
    Tout est question de choix. Windows aurait pu fournir ce que je demande. Comme je l'ai déjà dit, ce n'est pas vraiment génant puisqu'on peut le refaire soi-même. Bref, le sujet est clos
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

  15. #15
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    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 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    Dans mon code le CloseHandle n'y est pour rien, c'est juste que tu dois libérer le HANDLE qu'on te renvoie.
    Version plus courte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <windows.h> 
    
    DWORD WINAPI ThreadProc&#40; LPVOID  &#41; 
    &#123; 
        Sleep&#40; 3000 &#41;; 
        MessageBox&#40; 0, TEXT&#40; "Ca va couper!" &#41;, TEXT&#40; "" &#41;, 0 &#41;; 
        return 0; 
    &#125; 
    
    int main&#40;&#41; 
    &#123; 
        CreateThread&#40; NULL, 0, ThreadProc, 0, 0, NULL &#41;; 
        ExitThread&#40; 0 &#41;; 
    &#125;
    le thread principal lance un 2° thread et se termine. Pourtant le processus continue de tourner, car tous les threads ne sont pas terminés. Quans le 2° thread se termine, le process se termine aussi, automatiquement.

    C'est vrai que la fonction wait de Linux mentionne les "processus fils". Il y a donc une petite distinction avec Windows. Néamoins cette fonction est réelement très utile :
    c'est même un grosse différence. Et dans le contexte Win32, on utilise très peu les processus fils, contrairement à UNIX où on fork à tous va. En Win32 on utilise les threads. La notion de processus père n'est pas aussi forte sous Windows.

  16. #16
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Et pourtant il y a une librairie pthread sous Linux

    Merci pour tes indications. Je sais comment faire maintenant
    La vitesse de la lumière étant supérieure à celle du son, il apparaît normal que beaucoup de gens paraissent brillants jusqu'à ce qu'ils l'ouvrent.

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

Discussions similaires

  1. [Multi thread] Attendre la fin des threads
    Par rvzip64 dans le forum Langage
    Réponses: 4
    Dernier message: 12/05/2015, 10h53
  2. Réponses: 13
    Dernier message: 12/04/2011, 11h27
  3. Attendre la fin des animations sur un groupe
    Par SpaceFrog dans le forum jQuery
    Réponses: 13
    Dernier message: 19/03/2011, 22h49
  4. Réponses: 0
    Dernier message: 27/04/2009, 19h49
  5. [Thread] Un père qui doit attendre la fin des fils
    Par Chatbour dans le forum Concurrence et multi-thread
    Réponses: 9
    Dernier message: 09/09/2008, 14h29

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