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

MFC Discussion :

Fermeture de thread


Sujet :

MFC

  1. #1
    Membre averti
    Inscrit en
    Avril 2004
    Messages
    25
    D�tails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 25
    Par d�faut Fermeture de thread
    Bonjour,

    Je vous �cris afin de faire part d'un soucis dans l'un des tutos (et vous expliquer mon probl�me qui persiste :p) :
    http://c.developpez.com/faq/vc/?page...opWorkerThread
    Celui-ci consiste en l'arr�t d'un Thread MFC via l'utilisation "propre" des Handlers.

    J'ai une appli MFC bas� sur une CDialog. J'ai voulu mettre le tuto en place car j'ai un soucis (qui persiste) lorsque je veux arreter un thread en cours quand la CDialog est ferm�.
    J'arrive a fermer convenablement le thread lors d'un clic sur un bouton, mais pas lors de la fermeture de l'appli. Dans ce deuxi�me cas, j'ai un memory leak.

    Dans votre tuto, vous d�clarez deux fois des HANDLE. Certains en membres de la classe et d'autres dans le constructeur. Les premiers n'�tant pas utilis�s apr�s.
    Il me reste un probl�me concernant l'application de ce tuto : Si je suis le tuto � la lettre, le thread se termine bien, mais le
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ::WaitForSingleObject(m_hWaitThread, INFINITE);
    bloque l'appli malgr� la pr�sence de :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if(::WaitForSingleObject(pView->m_hEndThread, 0) == WAIT_OBJECT_0)
    {			
    	pView->m_sText = "Calcul annulé.";
    	::PostMessage(hWnd, MY_WM_UPDATE, (WPARAM)0, (LPARAM)0);
    	pView->m_cRatio.EnableWindow(true);
    	pView->m_bThread = false;
    	::SetEvent(pView->m_hWaitThread);
    	return result;
    }

  2. #2
    Membre chevronn� Avatar de stephdim
    Profil pro
    Inscrit en
    Ao�t 2007
    Messages
    462
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2007
    Messages : 462
    Par d�faut
    Bonjour,

    Effectivement il y a une petite erreur dans le tuto, je confirme ...

    Juste pour etre sure que l'evenement m_hWaitThread soit bien positionn�:

    Remplacer

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ::SetEvent(pView->m_hWaitThread);
    par

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    VERIFY(::SetEvent(pView->m_hWaitThread));
    Et executer l'appli en mode DEBUG

    Il y a aura une assertion si SetEvent() �choue. (mauvais handle par ex ..., ou le CreateEvent() a echou� par ex)


    @+

  3. #3
    Membre averti
    Inscrit en
    Avril 2004
    Messages
    25
    D�tails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 25
    Par d�faut
    Merci du conseil (que j'ai appliqu�). Je n'ai pas eu d'assertion.

    Il est a noter que j'ai deux moyens de demander l'arret du thread :
    - un bouton stop
    - ferme l'appli (le X en haut � droite de toute appli fen�tr�e windows :p )

    Si je ne met pas le "WaitForSingleObject" :
    Dans le 1er cas, je vois que le thread se termine nikel dans la fenetre Output. (sauf que j'attends pas proprement la fermeture du thread)
    Dans le 2eme cas, j'ai un memory leak d'un thread.
    Si je met le "WaitForSingleObject", dans les deux cas, j'ai mon appli bloqu�e...

    Si vous avez besoin d'autres parties du code... la j'ai cherch� un peu partout et appliqu� plusieurs tutos... j'comprends pas ce qu'il attend :s

  4. #4
    Membre chevronn� Avatar de stephdim
    Profil pro
    Inscrit en
    Ao�t 2007
    Messages
    462
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2007
    Messages : 462
    Par d�faut
    Ben j'ai du mal a voir sans voir l'implementation r�elle. Le tuto lui il marche

    Peux tu poster la partie qui cr�� le thread, signale l'arret et le corps du thread. (la boucle) --> �a c'est la partie debuggage

    Sinon je peux t'indiquer d'autres methodes plus ou moins simple.

    Tu peux faire pour cr�er ton thread:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    m_hEndEvent=CreateEvent(NULL,TRUE,FALSE,NULL);   // l'évènement pour commander le suicide du thread (m_hEndEvent=HANDLE)
    VERIFY(m_hEndEvent!=NULL);     // le mieux serait un vrai test et un message d'erreur
    m_pThread=AfxBeginThread(proc,param,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);    // création du thread mais suspendu (m_pThread=CWinThread*)
    VERIFY(m_pThread!=NULL);     // pareil un vrai test c'est mieux
    m_pThread->m_bAutoDelete=FALSE;     // pas d'auto-destruction de CWinThread
    m_pThread->ResumeThread();   // on démarre le thread
    Pour le d�truire:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    VERIFY(SetEvent(m_hEndEvent));       // suicide du thread
    VERIFY(WaitForSingleObject(m_pThread->m_hThread,INFINITE)==WAIT_OBJECT_0);    // attendre que le thread soit mort
    delete m_pThread;       // on peut detruire CWinThread
    CloseHandle(m_hEndEvent);     // on n'a plus besoin de l'evenement
    Dans le thread, suffit de v�rifier l'evenement m_hEndEvent :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    if (WaitSingleObject(hEndEvent,0)==WAIT_OBJECT_0)    // suicide ?
        return "code retour";           // on sort de la procedure

    Ca devrait marcher, grosso-modo c'est pareil que le tuto, on economise un "Event".

    En faisant WaitForSingleObject(m_pThread->m_hThread,INFINITE); la fonction rend la main qd le thread est fini ou tout de suite s'il est d�j� mort.
    Pas de risque de blocage

    @+

  5. #5
    Membre chevronn� Avatar de stephdim
    Profil pro
    Inscrit en
    Ao�t 2007
    Messages
    462
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2007
    Messages : 462
    Par d�faut
    Tu peux encore simplifier en rempla�ant l'evenement par un simple booleen. (�a fait pas tr�s academique, mais c'est vrai que dans ce contexte l� c'est du luxe )

    Ca donnerait:

    La cr�ation:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    m_StopThreadFlag=false;      // c'est un bool
     
    m_pThread=AfxBeginThread(proc,param,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
    m_pThread->m_bAutoDelete=FALSE;
    m_pThread->ResumeThread();
    L'arret:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    m_StopThreadFlag=true;
    WaitForSingleObject(m_pThread->m_hThread,INFINITE);
    delete m_pThread;
    Dans la boucle du thread:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    if (ptr->m_StopThreadFlag)
       return "code retour";
    c'est encore plus simple et �a marche tr�s bien si tu manipules le bool que de false vers true depuis n'importe quel autre thread.

    voila

    @+

  6. #6
    Membre averti
    Inscrit en
    Avril 2004
    Messages
    25
    D�tails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 25
    Par d�faut
    J'ai essay� un peu toutes les combisaisons avec les bool et les events.
    Ce que je constate c'est que mon thread se termine bien lorsque j'utilise mon bouton "stop", mais pas lors d'une fermeture de l'appli en cours de route.

    J'ai fait un essai :
    J'ai mis un AfxMessageBox lors de la fermeture afin de v�rifier que tout �tait bien appel� (on doute de tout dans ces cas la :p).
    J'ai bien ma fenetre qui pop et hoo miracle, mon thread se ferme � ce moment la. Donc mettre un WaitForSingleObject ou un sleep(10000) ca ne fonctionne pas, mais un AfxMessageBox... si.
    Je me demande ce que fait l'AfxMessageBox en "arri�re plan" qui manque � la lib�ration normale de mon thread.

    A savoir (pour completer), que pour intercepter la fermeture de l'appli j'intercepte le message WM_CLOSE.

  7. #7
    Membre averti
    Inscrit en
    Avril 2004
    Messages
    25
    D�tails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 25
    Par d�faut
    Bon, je me suis repench� sur la question et j'ai repris les tutos. Le fait de mettre l'arret dans le OnClose (message WM_CLOSE) m'avait mis un doute sur le moment ou la dialog lib�re ses variables etc.

    j'ai donc remis, comme dans le tuto, l'arr�t du thread dans le destructeur de ma CDialog :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CDialogDlg::~CDialogDlg()
    {
    	if(m_bThread == true) {
    		::SetEvent(m_hEndThread);
    		::WaitForSingleObject(m_hWaitThread, INFINITE);
    		Sleep(500);
    	}
    	::CloseHandle(m_hEndThread);
    	::CloseHandle(m_hWaitThread);
     
    }
    Comme vous voyez, j'ai mis un p�tit Sleep de 500ms pour rire apr�s avoir attendu l'event de fin de thread... ca marche.
    En fait, je pense que le debugguer de Visual d�tecte la fermeture de ma CDialog pour d�terminer les memory leaks... mais il se peut que le thread n'ai pas fini de lib�rer sa m�moire. (apr�s la lev�e de l'event, il reste le return � faire et � s'auto-terminer au thread.

    Enfin, il me fait plus de memory leak si je laisse le sleep.

  8. #8
    Membre chevronn� Avatar de stephdim
    Profil pro
    Inscrit en
    Ao�t 2007
    Messages
    462
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2007
    Messages : 462
    Par d�faut
    Le OnClose() est seulement appel� quand on ferme la fenetre par la croix ou Alt+F4. Il ne sera pas appel� si survient un DestroyWindow. (je suppose que c'est un dialogue modeless)

    --> Je placerais tout �a plutot dans OnPostNcDestroy.

    @+

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Fermeture de thread impossible
    Par cbegood dans le forum Windows Forms
    R�ponses: 2
    Dernier message: 13/10/2008, 10h28
  2. Fermeture de thread/Stopper recvfrom
    Par homeostasie dans le forum Visual C++
    R�ponses: 7
    Dernier message: 17/11/2006, 09h59
  3. [C#] - Probl�me sur fermeture d'un thread
    Par Erakis dans le forum Windows Forms
    R�ponses: 4
    Dernier message: 27/01/2006, 01h22
  4. Probleme fermeture Thread
    Par Raton dans le forum MFC
    R�ponses: 4
    Dernier message: 29/09/2005, 09h51
  5. [Thread][socket]Probl�me de fermeture d'un thread
    Par meda dans le forum Concurrence et multi-thread
    R�ponses: 4
    Dernier message: 04/11/2004, 01h03

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