A
thread class |
Une
classe thread |
WinThread is a simple thread class
that mimics the use of the VCL TThread class. It's an abstract base
class which means you have to derive your own class from it and
implement the Execute method where the main code of your thread must be. |
WinThread
est une classe qui implémente les threads Windows et imite le
fonctionnement de la classe TThread de la VCL. C'est une classe
abstraite et vous devez donc dériver votre propre classe de
celle-ci et implémenter la méthode Execute. |
#ifndef WINTHREAD_H
#ifndef WINTHREAD_H #define WINTHREAD_H //----------------------------------------------------------------- #include <windows.h> namespace mlLib { class CriticalSection { private: CRITICAL_SECTION cs_; public: CriticalSection() {InitializeCriticalSection(&cs_);} ~CriticalSection() {DeleteCriticalSection(&cs_);} void acquire() {EnterCriticalSection(&cs_);} void release() {LeaveCriticalSection(&cs_);} }; /** * Provide a safe way to use CriticalSection. * Imagine protecting data like this: * CriticalSection protect; * protect.acquire(); * //data to be protected * protect.release(); * If 'data to be protected' throws an exception, the critical * section will never be released. The class Lock avoid this * problem releasing the critical section when it goes out * of scope. */ class Lock { private: CriticalSection §ion_; public: Lock(CriticalSection §ion) : section_(section) { section_.acquire(); } ~Lock() {section_.release();} }; /** * To use WinThread, you have to derive your own thread class * from WinThread and implement the Execute() method which is * where your thread code is executed. * Winthread is created in suspended mode. To run the thread, * call Resume(). * The Execute() method should periodically check the state of * te Terminated property to know if another thread has requested * to terminate your thread. */ class WinThread { private: HANDLE handle_; DWORD id_; bool suspended_; CriticalSection cs_; static DWORD __stdcall ThreadFunc(void* arg); WinThread(const WinThread&); WinThread& operator=(const WinThread&); protected: virtual void Execute()=0; bool Terminated; public: WinThread(); virtual ~WinThread(); bool Create(); DWORD GetThreadId()const{return id_;} void Resume(); void Suspend(); void Terminate(); void WaitFor(DWORD delay=INFINITE); bool SetPriority(int priority); int GetPriority(); }; //----------------------------------------------------------------- } //end namespace mlLib #endif |
#include "winthread.h"
mlLib::WinThread::WinThread(): handle_(0),id_(0),suspended_(true),Terminated(false) { } mlLib::WinThread::~WinThread() { if(!Terminated && !suspended_) { Terminate(); WaitFor(); } if(handle_)CloseHandle(handle_); } bool mlLib::WinThread::Create() { handle_ = CreateThread(NULL,0,ThreadFunc,this,CREATE_SUSPENDED,&id_); if(handle_)return true; return false; } void mlLib::WinThread::Resume() { if(suspended_) { Lock protect(cs_); if(suspended_) { ResumeThread(handle_); suspended_ = false; } } } void mlLib::WinThread::Suspend() { if(!suspended_) { Lock protect(cs_); if(!suspended_) { SuspendThread(handle_); suspended_ = true; } } } void mlLib::WinThread::Terminate() { if(!Terminated) { Lock protect(cs_); if(!Terminated)Terminated = true; Resume(); } } void mlLib::WinThread::WaitFor(DWORD delay) { WaitForSingleObject(handle_,delay); } DWORD __stdcall mlLib::WinThread::ThreadFunc(void* arg) { WinThread *ptr=reinterpret_cast<WinThread*>(arg); if(ptr) { ptr->Execute(); ptr->Terminated = true; } return 0; } bool mlLib::WinThread::SetPriority(int priority) { return SetThreadPriority(handle_,priority); } int mlLib::WinThread::GetPriority() { return GetThreadPriority(handle_); } |
To use this class, as the Execute()
methode is declared as pure virtual, you must derive your own class
from the abstract base class WinThread. Your thread code is placed in
the body of your Execute() method and must check periodically if the
thread is requested to terminate. Below, a skeleton of a derived class from WinThread: |
La
méthode Execute() de la classe WinThread est
déclarée virtuelle pure ce qui veut dire que vous devez
l'implémenter dans votre classe dérivée de
WinThread. Dans le corps de la fonction, vous placez le code que doit
exécuter votre thread en testant régulièrement si
celui-ci doit se terminer. Ci-dessous, un squelette de classe dérivée de WinThread: |
#include "winthread.h"
class MyThread : public mlLib::WinThread { public: MyThread() : mlLib::WinThread() {} ~MyThread() {} private: void Execute(); }; void MyThread::Execute() { while (!Terminated) { // put your thread code here } } |
To download the WinThread class,
click here. Don't forget when you compile an application using threads to add the appropriate switches and to link to the appropriate multithread version of the runtime lib file. |
Pour
télécharger le code de la classe WinThread, cliquez ici. N'oubliez pas d'ajouter lors de la compilation, les switchs nécessaires et lors du link, d'inclure la version multithread des librairies. |