begin process at 2012 02 07 09:58:10
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > CLASSE CTHREAD

CLASSE CTHREAD


 Information sur la source

Note :
9,6 / 10 - par 5 personnes
9,60 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Classé sous :thread, virtuel, classe, heritage Niveau :Initié Date de création :07/05/2006 Date de mise à jour :18/12/2007 10:58:45 Vu / téléchargé :8 684 / 2 852

Auteur : bobbyantho

Ecrire un message privé
Commentaire sur cette source (17)
Ajouter un commentaire et/ou une note

 Description

Cette classe s'inspire de la classe Thread de Java. Elle peut aussi servir d'exemple de classe virtuelle.
Pour l'utiliser, il suffit de créer une classe, de la faire hériter de la classe CThread et de surcharger la méthode Run.

Source

  • #pragma once
  • #include <windows.h>
  • #define WM_STOPTHREAD WM_USER
  • class CThread
  • {
  • public:
  • enum Priority
  • {
  • Basse = THREAD_PRIORITY_LOWEST,
  • Normale = THREAD_PRIORITY_NORMAL,
  • Critique = THREAD_PRIORITY_TIME_CRITICAL,
  • TempsReel = REALTIME_PRIORITY_CLASS
  • }Priority;
  • private:
  • HANDLE m_hThread;
  • DWORD m_dwThreadId;
  • BOOL m_bActif;
  • //thread
  • friend DWORD WINAPI Thread(LPVOID pParam);
  • protected:
  • //fonction virtuelle appelée par le thread
  • virtual void Run(void) = 0;
  • public:
  • //constructeur
  • CThread();
  • //destructeur
  • ~CThread();
  • //lancer le thread
  • void Start(void);
  • //arrêter le thread
  • void Stop(DWORD dwTimeOut = INFINITE);
  • //terminer le thread (brutal)
  • void Terminate(void);
  • //changer la priorité
  • void SetPriority(int iPriority) const;
  • //retourne l'activité du thread
  • BOOL IsRunning(void) const;
  • //retourne le handle du thread
  • HANDLE GetHandle(void) const;
  • //retourne l'identifiant du thread
  • DWORD GetID(void) const;
  • //attend la fin du thread
  • DWORD Wait(DWORD dwTimeOut) const;
  • };
#pragma once

#include <windows.h>

#define WM_STOPTHREAD WM_USER

class CThread
{
	public:
		enum Priority
		{
			Basse = THREAD_PRIORITY_LOWEST,
			Normale = THREAD_PRIORITY_NORMAL,
			Critique = THREAD_PRIORITY_TIME_CRITICAL,
			TempsReel = REALTIME_PRIORITY_CLASS
		}Priority;

	private:
		HANDLE m_hThread;
		DWORD m_dwThreadId;
		BOOL m_bActif;

		//thread
		friend DWORD WINAPI Thread(LPVOID pParam);

	protected:
		//fonction virtuelle appelée par le thread
		virtual void Run(void) = 0;

	public:
		//constructeur
		CThread();
		//destructeur
		~CThread();
		
		//lancer le thread
		void Start(void);
		//arrêter le thread
		void Stop(DWORD dwTimeOut = INFINITE);
		//terminer le thread (brutal)
		void Terminate(void);
		//changer la priorité
		void SetPriority(int iPriority) const;
		//retourne l'activité du thread
		BOOL IsRunning(void) const;
		//retourne le handle du thread
		HANDLE GetHandle(void) const;
		//retourne l'identifiant du thread
		DWORD GetID(void) const;

		//attend la fin du thread
		DWORD Wait(DWORD dwTimeOut) const;
};


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

01 juillet 2006 14:29:07 :
J'ai corrigé les petites erreurs qui subsistaient et intégré un arrêt "en douceur" du thread (méthode Stop()). Pour ce faire, il faut implémenter dans la surcharge de la méthode Run un mécanisme tel que : void MaClasse::Run(void) { MSG Message; //boucle du thread while(...) { //si demande de fermeture if(PeekMessage((&Message,NULL,WM_STOPTHREAD,WM_STOPTHREAD,PM_NOREMOVE)) { //libération de la mémoire ... //sortie ExitThread(0); } ... } }
09 octobre 2006 18:13:22 :
Supression d'une variable inutile.
18 décembre 2007 10:57:35 :
Correction de quelques bugs.
18 décembre 2007 10:58:45 :
Correction de quelques bugs non pris en compte la dernière fois.

 Sources du même auteur

Source avec Zip Source avec une capture CLASSE CGRAPHXY
Source avec Zip CLASSE CLECTEURVIDÉO
Source avec Zip CLASSE CUSERINFO
Source avec Zip CLASSE CPIXEL
Source avec Zip CLASSE CBDD

 Sources de la même categorie

Source avec Zip WIN32 TLS LENT par dguilmain
Source avec Zip VIDER ELEMENTS DE CORBEILLE WINDOWS7 (WIN64) par BruNews
Source avec Zip Source avec une capture FIND TEXT (WIN64) par BruNews
Source avec Zip DELETE DIRECTORY (WIN64) par BruNews
Source avec Zip ENUM DIRECTORY (WIN64) par BruNews

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture SOKOBAN EN C POUR DÉBUTANT (VERSION AMÉLIORÉE BASÉE SUR LE T... par eustatika
Source avec Zip MINICHAT MULTI-CLIENT par wisar
Source avec Zip TIM_RESEAU, CLASSES POUR RESEAU COMPLET par williamallas
Source avec Zip HEAPCOLLECTOR par troctsch
Source avec Zip GSTRING - GESTION DES CHAINES DE CARACTÈRES par Neokript

Commentaires et avis

Commentaire de laurent1024 le 07/05/2006 11:34:11

Classe claire, qui a en plus l'air d'être simple à utiliser. Par contre, il y a un truc que je comprend pas :
CThread::~CThread()
{
//si thread actif
if(m_bActif)
{
//terminer
}
//initialisation
m_hThread = NULL;
m_dwThreadId = 0;
m_bActif = FALSE;
}

-> pourquoi une initilisation à la fin du destructeur ??

Commentaire de bobbyantho le 07/05/2006 11:49:39

C'est vrai que c'est inutile ici, mais j'ai pris l'habitude d'aussi initialiser mes données membres dans le destructeur à des fins pratiques.
Par exemple, lorsque je surcharge l'opérateur d'affectation(=), j'appelle explicitement le destructeur de la classe qui m'initialise en même temps les données membres.

Commentaire de lordskyser1 le 29/06/2006 15:09:29

Félicitation pour cette classe, pourrais tu donner un exmeple de surcharge de Run pour que l'on puisse exécuter la procédure que l'on veut stp?

Commentaire de bobbyantho le 30/06/2006 00:57:47

Voilà !

Considérons la classe CMaClasse définie comme suit :

//CMaClasse.h
#include "Thread.h"
class CMaClasse : public CThread
{
public:
   //constructeur et destructeur
   CMaClasse();
   ~CMaClasse();

private:
   //surcharge de la méthode Run
   void Run(void);
};

//CMaClasse.cpp
#include "MaClasse.h"
CMaClasse::CMaClasse()
{
}
CMaClasse::~CMaClasse()
{
}
void CMaClasse::Run(void)
{
   /*mettre ici le code à éxécuter dans le thread, par exemple pour un serveur TCP */

   //tant que le client est connecté
   {
      //si données recues
      {
         //interprétation des données
      }
   }
   //déconnexion du client
}

//main.cpp
#include "MaClasse.h"
int main(void)
{
   ...

   //déclarer un objet
   CMaClasse MaClasseObj;

   //lancer le thread
   MaClasseObj.Start();

   ...

   return 0;
}

Voilà, j'espère avoir répondu à ta question. (j'ai fait cette classe ServeurTCP dont je me suis servi pour l'exemple et je la mettrais bientôt sur le site).

Commentaire de lordskyser1 le 30/06/2006 08:10:11

merci, c'est parfait! par contre je vois juste un petit inconvénient : si on veu lancer plusieurs threads qui exécutent des procédures différentes, il faut faire deux classes différentes qui héritent de CThread, c'est çà? est-il possible de passer quelque part (constructeur ou méthode run) en paramètre le nom de la procédure à exécuter afin qu'à partir d'une même classe deux procédures différentes puissent être exécutées dans deux instances différentes?

Commentaire de bobbyantho le 30/06/2006 09:23:14

Oui, il faut en effet un objet par thread.
Si les threads doivent faire des choses différentes, il faudra créer une classe par tâche à effectuer. Si tu veux par contre appeler seulement des procédures différentes au sein de la même classe, le plus simple est d'utiliser les foncteurs. (je ne sais pas si je suis clair ?).

Un exemple :

//.h
class CMaClasse : public CThread
{
private:
   //pointeur sur la procédure à appeler fonction
   void (*m_pProc)(void);

public:
   //constructeur et destructeur
   CMaClasse();
   ~CMaClasse();

   //fonction de sélection de la procédure à appeller
   void SelectProc(void CMaClasse::(*pProcedure)(void));

private:
   //surcharge de la méthode Run
   void Run(void);
   //différentes procédures pouvant être appelées par le thread
   void Proc1(void);
   void Proc2(void);
   ...
};

//.cpp
#include "MaClasse.h"
CMaClasse::CMaClasse()
{
   //initialiser le pointeur à NULL
   m_pProc = NULL;
}
CMaClasse::~CMaClasse()
{
}
void SelectProc(void CMaClasse::(*pProcedure)(void))
{
   //initialiser le pointeur avec la fonction donnée
   m_pProc = pProcedure;
}
void CMaClasse::Run(void)
{
   //si une procédure est définie, l'appeler
   if(m_pProc)
      this->(*m_pProc)();
}

Ensuite, pour l'utiliser, c'est comme dans mon précédent exemple sauf que si l'on veut changer la procédure à appeler, on fait par exemple :

CMaClasse MaClasse1, MaClasse2;

MaClasse1.SelectProc(CMaClasse::Proc1);
MaClasse1.Start();

MaClasse2.SelectProc(CMaClasse::Proc2);
MaClasse2.Start();

Voilà, c'est la solution qui me parait la plus simple.

Commentaire de bobbyantho le 30/06/2006 09:24:57

Rectification, pas de foncteurs ici mais des pointeurs de fonctions !

Commentaire de lordskyser1 le 01/07/2006 12:42:51

super, merci de te décarcasser autant pour que je puisse comprendre. Aujourd'hui c'est le premier jour des vacances pour moi, mais je vais essayer çà très rapidement :) encore merci, pour la peine je te met 10/10 ^^ continue ainsi c'est parfait

Commentaire de bobbyantho le 01/07/2006 14:31:21

Merci !

Essaye plutôt avec la mise à jour que je viens de faire car l'ancienne version comprenait quelques bugs.

Bonnes vacances !

Commentaire de BruNews le 09/10/2006 17:51:46 administrateur CS

private:
  HANDLE m_hThread;
  DWORD m_dwThreadId;
  BOOL m_bActif;

Puisqu'il y a bien:
m_hThread = NULL;
dans le constructeur, m_bActif me semble perdre 4 octets pour rien.
m_hThread jouera parfaitement ce role, non ?

Commentaire de bobbyantho le 09/10/2006 18:05:36

Très juste, je corrige ça dès que possible.

Commentaire de roidelajungle le 18/12/2007 10:27:52

Salut,

j'essaye d'utiliser cette classe, et lorsque je compile le fichier Thread.cpp Visual C++ me retourne deux erreurs :

error C2065: 'm_hThread' : undeclared identifier
error C2065: 'm_dwThreadId' : undeclared identifier

et il me dit que cela concerne la fin du code dans Thread.cpp :

DWORD WINAPI Thread(LPVOID pParam)
{
//appeler la méthode run
((CThread*)pParam)->Run();

//fin du thread
CloseHandle(m_hThread);  // ici
m_hThread = NULL;
m_dwThreadId = 0;        // et là

return 0;
}

et je ne sais pas du tout quoi faire, vu que je n'ai modifier ni Thread.h ni Thread.cpp

bobbyantho peux-tu encore une fois éclairer ma lenterne?

Commentaire de bobbyantho le 18/12/2007 11:00:40

Effectivement, j'avais corrigé ces erreurs mais apparement l'upload du nouveau code ne s'est pas passé correctement.
Voilà qui est fait !

Voici le code correct :
DWORD WINAPI Thread(LPVOID pParam)
{
//appeler la méthode run
((CThread*)pParam)->Run();

return 0;
}

Commentaire de bobbyantho le 18/12/2007 11:01:24

-->

Il y a quelques autres modifs, je te conseille de re-télécharger le nouveau code.

Commentaire de kobi888 le 10/03/2008 15:55:24

Bonjour!

Classe très utile!!
Tu n'aurais pas d'équivalent sous linux?

merci

Commentaire de bobbyantho le 10/03/2008 20:59:49

Bonjour,

Regardes avec les objets thread de la stdlib qu'il serait possible d'encapsuler dans une classe telle que celle-ci.

Commentaire de Niamorh le 23/11/2008 20:21:45

Salut, c'est intéressant de regarder ta source car j'ai implémenté une classe de thread similaire, modulo quelques détails.

Notamment, la boucle de message est implémentée par ma classe de base. MA classe dérivée ne doit pas implémenter un Run() mais plutôt un OnMessage( Message* ).
Je peux donc créer un thread "inactif" et lui donner du travail via un .PostMessage( Message* ) (méthode de ma classede base, qui s'occupe de l'appel à l'API Win32). Du coup je n'ai nul besoin de méthodes GetHandle ou GetID, l'API est totalement encapsulée.

Si l'envoi d'un message a réussi, il est possible de faire un .Wait() sur le message pour attendre que le thread ait terminé de le traiter. Cela vient en plus du .Wait() de fermeture du thread.

a+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

heritage [ par ifren ] Salut , je fais un stage, et je veux avoir une idée dite (idiomatique) pour resoudre un probleme en c++Probleme: J'ai une classe C (abstra heritage [ par ifren ] Salut , je fais un stage, et je veux avoir une idée dite (idiomatique) pour resoudre un probleme en c++Probleme: J'ai une classe C (abstra 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 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 heritage de fonctions [ par jfk20004 ] Comment fait on lorsqu'on a definie une classe A qui herited'une autre B pour appeler les fonctions de la classe de base A pour qu'elles soient utili Synchronisation!!! [ par PunkDude424 ] J'ai un problème avec la synchronisation de ThreadVoilà, je fais un "ScreenSaver" qui affiche des point a des temps radom et dune durée random aussi.. Class derivée , Template ( POURQUOI ES-CE CI DIFFICILE) ??? [ par nawakator ] J'ai d&#233;j&#224; pos&#233; cette question, mais je la repose car elle est essentiel pour mon projet!J'ai cr&#233;er un template permettant de g&#23 classe heritage [ par abdoulax ] Bonjours, Je suis bloqu&#233; surun probleme d'heritage, voici la probl&#233;matique : Nous avons un objet soit carr&#233;, triangulaire ou rond. Mai c++ -> surcharge d'ope et heritage ... [ par Alligokouax ] je suis vraiment au bord du suicide, j'ai exam dans trois jours ... et c la merdecomment peux on faire et est ce que cela existe :utiliser la surcharg fonction recevant un pointeur de fonction d'une classe [ par fuliculi ] Bonjour &#224; tous,j'ai un thread qui doit faire &#233;voluer une variable "progress" de 0 &#224; 100% (j'utilise les mutex pour &#233;viter les &#23


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 : 0,952 sec (3)

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