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 :

ThreadManager et durée de vie d'un thread


Sujet :

Windows

  1. #1
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut ThreadManager et durée de vie d'un thread
    Bonjour,

    Je souhaite créer une classe ThreadManager qui gère des threads comme vous pouvez deviner.

    Cette classe fera appel à la fonction CreateThread(). Elle possede un compteur de threads. Cependant je ne sais pas comment faire pour savoir quand le thread s'est terminé afin que je puisse le décrémenter le compteur du manager.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    D'après le nom de ta classe, elle va s'utiliser comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TheadManager::CreateThread(MyThreadFunc, Params);
    Et bin, lorsque tu fais appel à CreateThread, tu ne passes pas directement MyThreadFunc mais plutôt une fonction membre statique.
    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
    struct ThreadParams {
        LPTHREAD_START_ROUTINE lpThreadStartRoutine;
        LPVOID lpParams;
    };
    
    ThreadManager::CreateThread(LPTHREAD_START_ROUTINE lpThreadStartRoutine, LPVOID lpParams)
    {
        ThreaParams Params;
    
        Params.lpThreadStartRoutine = lpThreadStartRoutine;
        Params.lpParams = lpParams;
    
        ::CreateThread(..., ManagerThreadStartRoutine, ... &Params);
    }
    
    ThreadManager::ManagerThreadStartRoutine(LPVOID lpParams)
    {
        ThreadParams * lpThreadParams = (ThreadParams *)lpParams;
    
        ThreadCount++;
        lpThreadParams->lpThreadStartRoutine(lpThreadParams->lpParams);
        ThreadCount--;
        GenererSignal(TEL_THREAD_S_EST_TERMINE);
    }
    C'est très brouillon mais toute l'idée est là.

    Tu peux aussi jouer avec les events si ça te tente ...

  3. #3
    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 518
    Points
    41 518
    Par défaut
    Et pourquoi pas directement le handle du thread?

    Un WaitForSingleObject() avec un timeout de zéro suffit à savoir si le thread est terminé ou non, un WaitForMultipleObjects() permet d'attendre le premier qui se termine...
    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.

  4. #4
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    J'ai géré ainsi:

    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
    typedef void (*PtrFunc)(void *, void *);
    
    class CThreadManager
    {
    public:
    	CThreadManager();
    	~CThreadManager();
    
    	bool CreateThread(void * lpObject, PtrFunc lpFunc, void * lpFuncParam);
    	size_t Count() const;
    
    private:
    	void RunThread(void * lpObject, PtrFunc lpFunc, void * lpFuncParam);
    	void AddThread();
    	void RemoveThread();
    
    	static DWORD WINAPI StartThread(LPVOID lpParam);
    
    	size_t m_iNbThread;
    };
    
    struct CThreadData
    {
    	CThreadManager * lpThreadManager;
    	void * lpObject;
    	PtrFunc lpFunc;
    	void * lpFuncParam;
    };
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    CThreadManager::CThreadManager() :
    	m_iNbThread(0)
    {
    }
    
    CThreadManager::~CThreadManager()
    {
    }
    
    bool CThreadManager::CreateThread(void * lpObject, PtrFunc lpFunc, void * lpFuncParam)
    {
    	CThreadData threadData;
    	threadData.lpThreadManager = this;
    	threadData.lpObject = lpObject;
    	threadData.lpFunc = lpFunc;
    	threadData.lpFuncParam = lpFuncParam;
    
    	HANDLE hThread = ::CreateThread(NULL, 0, static_cast<LPTHREAD_START_ROUTINE>(StartThread), &threadData, 0, NULL);
    
    	Sleep(100);
    
    	if (hThread && (hThread != INVALID_HANDLE_VALUE))
    	{
    		CloseHandle(hThread);
    		hThread = NULL;
    
    		return false;
    	}
    
    	return true;
    }
    
    void  CThreadManager::RunThread(void * lpObject, PtrFunc lpFunc, void * lpFuncParam)
    {
    	lpFunc(lpObject, lpFuncParam);
    }
    
    size_t CThreadManager::Count() const
    {
    	return m_iNbThread;
    }
    
    void CThreadManager::AddThread()
    {
    	++m_iNbThread;
    }
    
    void CThreadManager::RemoveThread()
    {
    	--m_iNbThread;
    }
    
    DWORD WINAPI CThreadManager::StartThread(LPVOID lpParam)
    {
    	CThreadData * lpThreadData = reinterpret_cast<CThreadData *>(lpParam);
    	CThreadManager * lpThreadManager = lpThreadData->lpThreadManager;
    	void * lpObject = lpThreadData->lpObject;
    	PtrFunc lpFunc = lpThreadData->lpFunc;
    	void * lpFuncParam = lpThreadData->lpFuncParam;
    
    	// On protège la variable interne via un mutex
    	{
    		CLock lock(TEXT("CThreadManager::StartThread"));
    		lpThreadManager->AddThread();
    	}
    
    	lpThreadManager->RunThread(lpObject, lpFunc, lpFuncParam);
    	
    	// On protège la variable interne via un mutex
    	{
    		CLock lock(TEXT("CThreadManager::StartThread"));
    		lpThreadManager->RemoveThread();
    	}
    	
    	return 0;
    }
    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
    void CRemoteAdminDlg::OnOpen()
    {
    	// Manager de threads
    	CThreadManager mgr;
    
    	// Ouverture message d'attente
    	if(lpDialogWaitTh)
    		pDialogWaitTh->OpenWindow();
    
    	// Ouverture des bornes dans des threads parallèles
    	for (int i(0);i<iIndex;i++)
    	{
    		mgr.CreateThread(this, &CRemoteAdminDlg::OpenTerminal, &i);
    	}
    
    	// Tant qu'il reste des threads lancés
    	while (mgr.Count() > 0)
    	{
    		Sleep(100);
    	}
    
    	// Fermerture message d'attente
    	if(lpDialogWaitTh)
    		pDialogWaitTh->CloseWindow();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void CRemoteAdminDlg::OpenTerminal(void * lpObject, void * lpParam)
    {
    	CRemoteAdminDlg * lpRemoteAdminDlg = reinterpret_cast<CRemoteAdminDlg *>(lpObject);
    	int * lpNum = reinterpret_cast<int *>(lpParam);
    	int iNum = *lpNum;
    
    	// Traitement
    }
    Ca marche très bien.

  5. #5
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Et pourquoi pas directement le handle du thread?

    Un WaitForSingleObject() avec un timeout de zéro suffit à savoir si le thread est terminé ou non, un WaitForMultipleObjects() permet d'attendre le premier qui se termine...
    Car je veux pas bloquer sur chaque thread, mais sur l'ensemble des threads.
    J'affiche une fenêtre de dialogue au lancement des threads, et une fois tous les threads finis, je referme cette fenêtre.

    La solution que j'ai développée entre temps (qui se rapproche de la proposition de Melem) fait justement ça.

  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 518
    Points
    41 518
    Par défaut
    WaitForMultipleObjects() aussi.
    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 averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    WaitForMultipleObjects() aussi.
    Au temps pour moi alors
    Je vais y jeter un oeil, ça devrait simplifier pas mal le code.

  8. #8
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Quand j'y pense, en effet. Mais au moment où je postais je n'étais pas aussi sûr, en plus en réfléchissant bien, c'est à peine si va simplifier le code. Ça va juste le changer.

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

Discussions similaires

  1. [C#] : Durée de vie d'un thread
    Par dcollart dans le forum C#
    Réponses: 2
    Dernier message: 04/12/2006, 18h08
  2. [Cookies] durée de vie de l'objet
    Par ozzmax dans le forum Langage
    Réponses: 13
    Dernier message: 13/01/2006, 21h38
  3. [savoir] durée de vie d'un PC?
    Par afrikha dans le forum Composants
    Réponses: 20
    Dernier message: 24/10/2005, 13h28
  4. [AS2] durée de vie d'une classe (extends movieclip)
    Par ooyeah dans le forum ActionScript 1 & ActionScript 2
    Réponses: 4
    Dernier message: 23/07/2005, 13h33
  5. prob de durée de vie de IDvdGraphBuilder
    Par Chaksss dans le forum DirectX
    Réponses: 11
    Dernier message: 30/12/2004, 16h09

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