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 :

Interruption propre d'un thread


Sujet :

MFC

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 99
    Points : 52
    Points
    52
    Par défaut Interruption propre d'un thread
    Bonjour,

    je fais appel à une fonction "Common()" définie dans une DLL pour effectuer un traitement qui peut etre trés long dans une partie de mon programme. J'aimerais que ce traitement s'arrete si son temps d'execution dépasse les 30s, meme s'il n'est pas terminé. Je mise sur les threads pour gérer cette problématique, mais ca ne fonctionne pas correctement...

    J'ai écrit une classe héritant de CWinThread : CCommonThread
    Dans la propriété "Run()" de cette classe, j'ai placé la fonction "Common()" de ma DLL.
    Dans mon programme, je lance ainsi le nouveau thread :
    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
     
    CCommonThread* pAdapter = (CCommonThread*)AfxBeginThread( RUNTIME_CLASS(CCommonThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
    pAdapter->m_bAutoDelete = FALSE;
    pAdapter->ResumeThread();
     
    DWORD exitCode;
    if ( ::WaitForSingleObject( pAdapter->m_hThread, 30000) == WAIT_TIMEOUT )
    {
        exitCode = 1;		
    }
    else
    {	
        exitCode = 0;
    }
    pAdapter->PostThreadMessage( WM_QUIT, 0, 0);
    Cela fonctionne au premier passage, mais ensuite, dés que je veux utiliser des fonctionnalités de la DLL, mon appli plante. J'ai l'impression que la DLL n'est pas proprement libérée à la fermeture du thread...

    Auriez-vous une idée pour résoudre ce genre de problème. Y a-t-il une issue sans utiliser les threads ?
    Tous les exemples de mise en place d'une solution threadée (trouvés sur le web) montre une boucle de traitement dans l'execution du thread. La terminaison du thread s'effectue de lui-meme en mettant une fin à cette boucle. Je ne suis pas dans cette situation, car dés que le thread appelle la fonction "Common()" de la DLL, je n'ai plus la main...

    Merci pour votre coup de main !!!

  2. #2
    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
    WM_QUIT signifie seulement que la boucle de messages du thread destinataire doit se terminer après le prochain GetMessage(). Si ton thread n'a pas de boucle de messages, ça ne lui fera rien.
    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.

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 99
    Points : 52
    Points
    52
    Par défaut
    Je pense que mon thread gère bien une boucle de message : c'est un thread UI créée avec DECLARE_DYNCREATE, IMPLEMENT_DYNCREATE et DECLARE_MESSAGE_MAP() dans la déclaration et l'implémentation de la classe !

    Voici le code de l'entete et de la définition des propriétés :

    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 CCommonThread : public CWinThread
    {
    	DECLARE_DYNCREATE(CCommonThread)
    public:
    	CCommonThread();  
    	virtual ~CCommonThread();
            virtual int Run() ;
            virtual int ExitInstance() ;
            virtual BOOL InitInstance();
     
    	TopoDS_Shape forme1_;
    	TopoDS_Shape forme2_;
     
    protected:
    	DECLARE_MESSAGE_MAP()
    };
     
    IMPLEMENT_DYNCREATE( CCommonThread, CWinThread)
    CCommonThread::CCommonThread()
    {
    }
    CCommonThread::~CCommonThread()
    {
    }
    BEGIN_MESSAGE_MAP(CCommonThread, CWinThread)
    END_MESSAGE_MAP()
    int CCommonThread::Run()
    {	
    	Common( forme1_, forme2_ );	       
     
    	return (0) ;
    }   
    BOOL CCommonThread::InitInstance()   
    {       
       return ::InitInstance();   
    }   
    int CCommonThread::ExitInstance()   
    {   
    	//AfxEndThread( 0 ); 
    	//ExitThread( 0 );
    	PostQuitMessage(0);
     
    	return CWinThread::ExitInstance();   
    }

  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
    Es-tu sûr que c'est un thread UI? Si j'ai bien compris, ton calcul long est dans la fonction Common(). Si oui, c'est cette fonction qui doit contenir une boucle de messages pour que ton thread soit un thread UI.
    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 du Club
    Inscrit en
    Janvier 2006
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 99
    Points : 52
    Points
    52
    Par défaut
    Je ne peux malheureusement rien faire avec la fonction "Common()" qui est définie dans une DLL qui n'est pas de mon ressort et dont je n'ai pas le code source...

  6. #6
    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
    Hé bien c'est mort alors. On ne peut interrompre proprement un thread que s'il nous aide à l'interrompre.
    Sinon, on ne peut l'interrompre que salement, ce qui comporte des risques pour l'intégrité du programme (imagine un TerminateThread() qui tomberait au beau milieu d'un malloc(), pendant que les listes chaînées du tas sont dans un état intermédiaire, et que le thread possède le verrou dessus!)
    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.

  7. #7
    Membre émérite
    Avatar de TheGzD
    Homme Profil pro
    Ingénieur/ Docteur en Informatique
    Inscrit en
    Avril 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur/ Docteur en Informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 327
    Points : 2 677
    Points
    2 677
    Par défaut
    Commence par changer ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pAdapter->m_bAutoDelete = TRUE;
    Ensuite dans le cas où ton thread a dépassé les 30s d'exécution essaye de passer les instructions suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pAdapter->Delete();
    ::WaitForSingleObject(pAdapter->m_hThread, INFINITE);
    En espérant que ça règle le problème.
    Vous postez du code ? Merci d'utiliser les balises
    Un message vous paraît pertinent ? Merci de le gratifier d'un vote positif
    Vous avez obtenu une réponse à votre question ? Merci d'utiliser le tag
    __________________
    Ingénieur R&D, diplômé en 2007 de l'ISIMA
    Docteur en informatique, diplômé en 2015 de l'EDSPI de Clermont-Ferrand

  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
    Pardonne mon franc-parler, mais c'est pourri:
    1. Le destructeur de CWinThread (et à fortiori CWinThread:elete()) ne fait rien pour interrompre le thread, il se contente de fermer son handle.
    2. Tu fais un Delete() (qui fait un delete this) juste avant d'accéder à un membre de la classe: Boum! comportement indéfini.
    3. Tu utilises le handle qui comme dit en 1, vient d'être fermé.
    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 du Club
    Inscrit en
    Janvier 2006
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 99
    Points : 52
    Points
    52
    Par défaut
    J'avais effectivement essayé ce genre de chose en controlant le "delete", mais évidemment sans succés : l'utilisation de la Dll contenant la fonction "Common()" est par la suite impossible, le moindre accés fait planter le soft...
    Pourtant j'imagine ne pas etre la premiere personne à vouloir faire ce genre de chose, non ?... Déception ;o(

  10. #10
    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
    Hélas, sur la plupart des platformes, le seul moyen d'interrompre proprement une chose, c'est si la chose en question se laisse interrompre.

    En natif sous Windows, la seule chose qu'on puisse interrompre salement sans trop de répercussions, c'est un processus entier. Interrompre salement un thread porte un risque significatif de corruption du processus autour.
    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.

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

Discussions similaires

  1. [QThread] Fermeture propre d'un thread
    Par Invité dans le forum Multithreading
    Réponses: 3
    Dernier message: 11/04/2013, 14h06
  2. Interruption et reprise d'un Thread
    Par Nuro dans le forum Concurrence et multi-thread
    Réponses: 1
    Dernier message: 28/02/2007, 21h34
  3. Interruption d'un Thread
    Par doudblast dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 11/03/2006, 17h30
  4. interrupt() de la classe thread
    Par canigu dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 25/12/2005, 14h01
  5. Interruption de thread
    Par bigben89 dans le forum Windows
    Réponses: 2
    Dernier message: 13/10/2005, 10h41

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