begin process at 2012 02 08 21:09:11
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Windows

 > 

System

 > 

Probleme fermeture de Thread!!!


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Probleme fermeture de Thread!!!

mercredi 11 juin 2008 à 11:00:50 | Probleme fermeture de Thread!!!

Dryko

Bonjour,

Je suis en train de programmer une application MFC dans lequel je créer un thread (avec CreateThread) dans le constructeur de ma classe.
Dans le destructeur de ma classe, je detruit (enfin j'essaye c'est la mon probleme) le thread avec TerminateThread.

Mon application marche parfaitement mais lorsque je la ferme, j'ai un gros message d'erreur "L'instruction à "0x00b1234" emploie l'adresse mémoire "0x00b1234". La mémoire ne peut être "read""......... :(

Apres un nombre incalculable de test, j'ai compris que cela venais de la destruction du thread (je ne pense pas que cela vienne de la creation vu qu'il marche tres bien) car si je ne le créé pas, je n'ai pas de pb et si je le créé et que je met seulement une boucle while infinie ca plante!!!...
J'ai beau avoir essayer toute les configurations de fermeture de thread telles :
terminatethread
exit thread
closehandle
getexitcodethread
.....
J'ai essayé tout ca dans tout les sens : tjours la meme erreur!!!!!!

Aidez moi je vous en supplie je vais craquer!!!!!

Merrci d'avance
mercredi 11 juin 2008 à 11:50:31 | Re : Probleme fermeture de Thread!!!

BruNews

Administrateur CodeS-SourceS
TerminateThread est à proscrire en utilisation normale, c'est une fonction d'urgence à n'employer que ponctuellement.

CreateThread est à remplacer par les fonctions MFC.

ciao...
BruNews, MVP VC++
jeudi 12 juin 2008 à 11:08:26 | Re : Probleme fermeture de Thread!!!

pipocodesrc

J'utilise le truc plus bas sans aucun soucis dans une classe perso.
hope this help

class Thread
{
private:
  HANDLE  _handle;
  dword      _idth;
  bool        _created,                       // true is create succesfully
                _exitmainloop;               // used in MainLoop
                _exitthread;
  int         _term_nbtry,_term_wait;  // used for Stop

public:

Thread()
{
_handle   =null;
_created=false;
_exitmainloop=false;
_exitthread=false;
}

bool Create()
{
  _handle = (HANDLE) __beginthreadex       
        (&Thread::STATIC_MainLoop,
         4096,                                // Thread stack size
         this,                                 // Thread start argument
         0,//&sa,                            // Thread security
         CREATE_SUSPENDED,   // Create in suspended state
         &_idth);                            // Thread ID.
 _created=_handle!=INVALID_HANDLE_VALUE;
return _created;
}

//main process
MainLoop()
{
 _exitmainloop=false;
  if (_created) while (!ExitLoop())  { cout<<'.'; Sleep(100); }
 _exitmainloop=true;
 _endthreadex(0);
}

inline bool ExitLoop() { return _exitthread; }

inline bool Created() { return _created; }
inline dword Start () {  return  ResumeThread(_handle); } // fails  if == 0xFFFFFFFF otherwise succeed
inline dword Pause () {  return SuspendThread(_handle);  } // fails  if == 0xFFFFFFFF otherwise succeed
bool Stop (dword ms=250,word nbretry=40)
{
  _term_nbtry=0;
  _term_wait =ms;
  _exitthread=true;           // if stopped when I restart the exitloop returns true

  bool  ok=false;
  dword thstatus;

  if (!_exitmainloop) 
  do
  {
   _waitstatus=WaitForSingleObject (_handle, ms);
   switch (_waitstatus)
    {
    case WAIT_ABANDONED : ok=true; break;
    case WAIT_TIMEOUT   :      break;
    case WAIT_OBJECT_0  : ok=true; break;
    case WAIT_FAILED    : ok=true; break;//can happen if handle is invalid  because already stopped
    //default           : ok=true;       // in other case, exit because an error occurs
    }
   if (!ok)
   {
    if (GetExitCodeThread (_handle, &thstatus))
     if (thstatus == STILL_ACTIVE)
     {
      cout<<endl<<" still active"
    }
   }
  }
  while (++_term_nbtry<nbretry && !ok && !_exitmainloop);

  if (!ok || !_exitmainloop) return false;

  CloseHandle(_handle); //must be called when _exitthreadex( rather _exitthread )
  _handle=null;
  _created=false;

  return true;
}

};

jeudi 12 juin 2008 à 11:37:08 | Re : Probleme fermeture de Thread!!!

Dryko

merci pipoco!
je vais tester dans quelques minutes...
mais dis moi : ton code attend que le thread ai fini de tourner ou le programme principal le tue meme si il a pas fini?..
merci
jeudi 12 juin 2008 à 11:46:03 | Re : Probleme fermeture de Thread!!!

pipocodesrc

Il attend qu'il est fini de tourner et que le handle soit libéré par un WaitForSingleObject ...
Si tu ne veux pas attendre utilise Terminate... mais mauvais choix si tu restes dans ton appli sinon l'OS se chargera  de gérer.
Si tu reste dans ton appli il faut que tu testes ExitLoop () dans la répétition du while (!ExitLoop()) ..ou ailleurs qui en dépend.

while (!ExitLoop()) ..
{
  code court ... //pas besoin de tests

  code long ...
  if (ExitLoop ()) break;

....

}
..

vendredi 13 juin 2008 à 09:21:29 | Re : Probleme fermeture de Thread!!!

Dryko

encore merci!

Pour le Terminate je sais que ce n'est pas propre mais mon Thread ne s'arrete jamais, c'est au main de lui dire de s'arreter. C'est pourquoi j'ai adopté une méthode basic : j'ai transformé la boucle infinie du thread en while(stop==false) et c'est le main qui passe le bool à true quand il s'arrete.

Mais En fait je me suis aperçu que le probleme ne venait pas de là... En fait, le programme que je vous ai décrit est un filtre DirectShow. J'utilise ce filtre dans une application MFC dans lequel je créé un graphe DirectShow. Lorsque je ferme l'application, il me detruit bien le graphe mais il ne me "detruit" pas le filtre, donc il ne rentre pas dans le destructeur du filtre et donc ne termine pas le thread.
Je sais pas pourquoi le filtre continue a tourner malgré le graphe soit bien detruit... une ptite idée??...

merci d'avance
vendredi 13 juin 2008 à 09:35:31 | Re : Probleme fermeture de Thread!!!

pipocodesrc

Salut, qu'est-ce que vous utilisez comme classe de filtre ? car qui dit exit d'application maîtrisée, dit clean de tout l'environnement (stop engine filter ...) donc arrêt de filtre même en train de processer. Vous vous êtes basé sur un sample du sdk ?
...

vendredi 13 juin 2008 à 11:38:16 | Re : Probleme fermeture de Thread!!!

Dryko

Ben en fait c'est un peu compliqué.... même beaucoup
en fait c'est un filtre que j'ai chopé sur le net :
quand le filtre est créé ca créé une classe qui fait pratiquement que le createinstance et qui lui appelle une autre classe qui fait "tout le travailé".... et je pense que la destruction du filtre detruit la premiere classe mais pas la deuxieme..
voila mon .h, si tu veux jeter un oeil :

#include "freeimage.h"
#include <iostream>
#pragma once

#define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr);

static const GUID CLSID_VirtualCAM;

class CVirtualCamStream;

/**
* @struct thread_param Structure de declaration de thread
* @param cvcs est une classe CVirtualCamStream
* @param soc : socket sur laquelle le programme va recevoir les paquets UDP
*/
struct thread_param{
 CVirtualCamStream* cvcs;
 SOCKET soc;
 MEMOIRE memoire[NOMBRE_MEMOIRE];
};

class CVirtualCam : public CSource
{
public:
    //////////////////////////////////////////////////////////////////////////
    //  IUnknown
    //////////////////////////////////////////////////////////////////////////
    static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
 

    IFilterGraph *GetGraph() {return m_pGraph;}

private:
    CVirtualCam(LPUNKNOWN lpunk, HRESULT *phr);
};

class CVirtualCamStream : public CSourceStream, public IAMStreamConfig, public IKsPropertySet
{
public:
 
 /**
 * Fonctions d'initialisation et de destruction de socket
 */
 SOCKET CVirtualCamStream::SocketInitialise(SOCKET sock);
 void CVirtualCamStream::SocketDeInitialise(SOCKET sock);
 
 /**
 * Fonction de creation de thread qui permet de faire tourner en parallele la fonction de reception des paquets
 */
 static DWORD WINAPI CVirtualCamStream::ThreadReceptionImage(void *p)
 {
  struct thread_param *Obj = reinterpret_cast<struct thread_param*>(p);
  
  CVirtualCamStream *c = Obj->cvcs;
  return c->ReceptionImage(Obj->soc); 
 }

    //////////////////////////////////////////////////////////////////////////
    //  IUnknown
    //////////////////////////////////////////////////////////////////////////
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
    STDMETHODIMP_(ULONG) AddRef() { return GetOwner()->AddRef(); }                                                          \
    STDMETHODIMP_(ULONG) Release() { return GetOwner()->Release(); }

    //////////////////////////////////////////////////////////////////////////
    //  IQualityControl
    //////////////////////////////////////////////////////////////////////////
    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);

    //////////////////////////////////////////////////////////////////////////
    //  IAMStreamConfig
    //////////////////////////////////////////////////////////////////////////
    HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt);
    HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt);
    HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize);
    HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC);

    //////////////////////////////////////////////////////////////////////////
    //  IKsPropertySet
    //////////////////////////////////////////////////////////////////////////
    HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, DWORD cbInstanceData, void *pPropData, DWORD cbPropData);
    HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, void *pInstanceData,DWORD cbInstanceData, void *pPropData, DWORD cbPropData, DWORD *pcbReturned);
    HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);

    //////////////////////////////////////////////////////////////////////////
    //  CSourceStream
    //////////////////////////////////////////////////////////////////////////
    CVirtualCamStream(HRESULT *phr, CVirtualCam *pParent, LPCWSTR pPinName);
    ~CVirtualCamStream();

    HRESULT FillBuffer(IMediaSample *pms);
    HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc, ALLOCATOR_PROPERTIES *pProperties);
    HRESULT CheckMediaType(const CMediaType *pMediaType);
    HRESULT GetMediaType(int iPosition, CMediaType *pmt);
    HRESULT SetMediaType(const CMediaType *pmt);
    HRESULT OnThreadCreate(void);
 HRESULT ShutdownThread( );

private:
    CVirtualCam *m_pParent;
    REFERENCE_TIME m_rtLastTime;
    HBITMAP m_hLogoBmp;
    CCritSec m_cSharedState;
    IReferenceClock *m_pClock;
 FILE* pFile;

 /**
 * @param sock correspond à la socket sur laquelle nous communiquons
 * @param WSAData utile pour la création de la socket
 */
 SOCKET sock;
 WSADATA WSAData;
 

 /**
 * Cette fonction doit être déclarée en static car appelée par un thread
 */
 DWORD ReceptionImage(SOCKET sock);

 HANDLE hthread;
 DWORD hthreadId;
 HANDLE m_hShutdownEvent;

 bool stop;
 
};

encore merci de t'interesser a mon cas ;)
 

vendredi 13 juin 2008 à 17:37:31 | Re : Probleme fermeture de Thread!!!

pipocodesrc

Salut,
Tout destructeur de classe appelle les destructeurs dont il dépend dans l'ordre d'héritage.
Si tu as des classes déclarées et non héritées il faut appeler explicitement celles-ci pour les détruire (sic);
J'ai regardé directshow (en travers), et ai utilisé un sample.
Je pense que cela vient de ton code et de sa structure implantée dans ton prog.
Elle fait quoi la fonction ReceptionImage.
Ton filtre doit s'arrêter, il y a un engine (thread) qui n'est pas stoppé regarde la doc ..., il y a certainement (obligatoirement) une api ou un callback qui permet de stopper l'acquisition/filtrage et de sortitr proprement.
...

lundi 16 juin 2008 à 09:35:26 | Re : Probleme fermeture de Thread!!!

Dryko

Salut, je n'avais pas acces à Internet ce we, c'est pourquoi je n'ai pas pui répondre,

-Pour les destructeurs je suis d'accord mais ma classe CVirtualCam n'en a pas et si j'en créé un, il n'est pas apelé quand je detruit mon graphe DirectShow. :(
-La fonction ReceptionImage communique avec un autre PC et ne s'arrete jamais, c'est quand on detruit le graphe qu'on doit lui dire de s'arreter!
-Pour l'API qui permetterait de tout stopper proprement, là j'avoue que je bloque un peu(beaucoup).

Merci

1 2

Cette discussion est classée dans : application, probleme, fermeture, classe, thread


Répondre à ce message

Sujets en rapport avec ce message

Lancer une thread intraclasse [ par rudyg ] Salut tout le monde,depuis une methode de classe, je souhaite lancer une thread faisant appel a une AUTRE methode de la meme classe.Ex:void kernel::La Pointeur et objet ET collection d'objet [ par MrKribou ] En fait je savais pas trop quoi mettre comme titre pour pas copier :pBon je vous explique mon probleme (j'ai pas le source de ce probleme sous la main Help !!! Probleme de Boite de Dialogue dans une toolbar ie [ par Stephcoet ] Je suis en train de développer un pluggin sous Internet Explorer permettant d'afficher une barre d'outil par laquelle différentes actions seront lancé Classe Thread [ par karakompact ] Pour mon travail et dans le but de créer une application, il me faut développer une classe Thread permettant de gerer le multitache..J'ai déjà ce type Probleme de fenetrage avec MFC VC++ [ par MaDC ] Salut tlm!J'dois faire une fenetre (identification) qui s'ouvre a l'initialisation de mon application MFC dans le constructeur de mon appliView. Pour Probleme avec une source [ par flatmax ] salut a tousca fait des jours que j'essaye d'utiliser une classe créé par un membre sur ce site, mais sans succes :(la source se trouve ici :http://ww probleme sur les class [ par JRB ] g trouve un cour sur les applications reseaux mais il manque des explications si quelqu'un pourrait me les apporrtais sa serais super je cherche a ajo SOS : Impossible d'acceder a certains champs ! [ par haccounsoft ] Salut à tous et merci d'avance a ceux qui tenteront de m'aider.Mon probleme n'est pas un probleme lié directement au C++, il concerne les tableaux d'o directX avec c++Builder [ par pro69 ] J'ai un petit probleme lorsque j'essaye de compiller des projet directX avec c++Builder. Les probleme commence deja quand je tempte d'utiliser le winm probleme creation dll de classe [ par juju cogne ] Voila j'ai codé une classe (.h et cpp) et je voudrais passer cette classe avec ses méthodes ainsi que les méthodes globales de cette application dans


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,170 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales