Здраствуйте, уважаемые жители RSDN.
Представляю вашему вниманию класс который разработал год назад. Он до сих пор не потерял своей актуальности, и думаю еще долго не потеряет.
Кстати переделывание старых проектов для работы через этот класс занимало минимум усилий. Но, возможно, это оттого, что я автор. Надеюсь мне все же удастся донести до общественности основные идеи.
К идее создания этого класса меня привела досадная неполноценность ряда операционных систем от одной мелкомягкой компании. Фукция TerminateThread появилась только в Win2k, да и то она убивает поток, а выделенные ресурсы так и остаются, до смерти самого процесса. Хочется чего-нибудь краткого и мощного. Это и было сделано.
// thread.h: interface for the threadable class.
//
// Design by Petrov Evgeniy with Todyshev Sergey 2001
//////////////////////////////////////////////////////////////////////
#ifndef _THREAD_INC_HEADER
#define _THREAD_INC_HEADER
/*concept:
Испокон веков поток реализовывался одной функцие примерно следующего вида.
UINT ThreadFunc(LPVOID pData)
{
...
Инициализация - в полном смысле этого слова
...
while(need_continue)
{
....
Поток что-то делает
....
}
...
Завершение (всякого рода освобождение ресурсов)
...
return _retval;
}
Естественно различные задачи требуют различной реализации, данный подход применим лишь
для самой популярной модели.
И, коль скоро удалось применить декомпозицию к такой сущности как Поток, то логично
агрегировать эти части в класс, что и сделано ниже.
Инициализация.
Шаг.
Завершение.
Имеено на эти части можно разбить любой нормальный поток.
*/
/*
Зачем все это нужно?
Обычный поток недостаточно управляем. Поскольку все собрано в одной функции, нет
возможности манипулировать отдельными частями. Предлагаемый класс достаточно легко и
интуитивно позволяет манипулировать потоком.
*/
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma warning(disable:4786)
#pragma warning(disable:4800)
#include "semaphore.h"
#include <map>
using namespace std;
// Флаги состояния потока
#define _THREAD_STATUS_UNKNOWN 0x000
#define _THREAD_STATUS_STARTED 0x001
// Поток в работе (т.е в основном цикле)
#define _THREAD_STATUS_SUSPENDED 0x002
// Поток приостановлен
#define _THREAD_STATUS_FINISHING 0x004
// Идет завершение
#define _THREAD_STATUS_STARTING 0x008
// Идет инициализация
class cThread: public semaphore
{
public:
// Инициализация данных, для данного экземпляра потока.
//Реализуется соответствующим классом потомком.
virtual bool Init()throw(){return true;}
// Один шаг цикла.
virtual bool Step() throw() = 0;
// Завершение.
virtual int Finish(){return 0;};
private:
DWORD dwThreadId;
HANDLE hThread;
int nSleepTime;
int nStatus;
private:
static unsigned long __stdcall Run(void* buf);
private:
//Блок управления флагами потока
void Finishing(){ nStatus |= _THREAD_STATUS_FINISHING ; }
void Starting(){ nStatus |= _THREAD_STATUS_STARTING ; }
void Suspended(){ nStatus |= _THREAD_STATUS_SUSPENDED; }
void Resumed(){ nStatus &= ~_THREAD_STATUS_SUSPENDED; }
void Started(){ nStatus |= _THREAD_STATUS_STARTED; }
void Stoped(){ nStatus &= ~_THREAD_STATUS_STARTED; }
public:
cThread():dwThreadId(0),hThread(0),nStatus(_THREAD_STATUS_UNKNOWN)
{
SetDelay();
}
public:
/* Блок управления потоком*/
// Начать поток
virtual int Start(BOOL bSuspended=FALSE, int StackSize=0);
// Приостановить поток
int Suspend();
// Разбудить поток
virtual int Resume();
// Остановить поток
virtual int Stop();
public:
int SetDelay(int dt=50){ return nSleepTime = dt; }
int GetDelay() const {return nSleepTime;}
int SetPriority(int prior) { return IsStarted()?SetThreadPriority(hThread,prior):THREAD_PRIORITY_ERROR_RETURN;}
int GetPriority(int prior) const { return IsStarted()?GetThreadPriority(hThread):THREAD_PRIORITY_ERROR_RETURN;}
private:
bool IsFinishing() const { return nStatus & _THREAD_STATUS_FINISHING; }
bool IsStarting() const { return nStatus & _THREAD_STATUS_STARTING; }
public:
bool IsSuspended() const { return nStatus & _THREAD_STATUS_SUSPENDED; }
bool IsResumed() const { return !IsSuspended(); }
bool IsStarted() const { return dwThreadId!=0&&hThread!=0&&(nStatus & _THREAD_STATUS_STARTED); }
bool IsStoped() const { return !IsStarted(); }
};
#endif // _THREAD_INC_HEADER
А вот реализация.
// thread.cpp: implementation of the threadable class.
//
// Design by Petrov Evgeniy with Todyshev Sergey 2001
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "thread.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
unsigned long cThread::Run(void* buf)
{
cThread * pThread = (cThread*)buf;
if(pThread->Init())
{
pThread->nStatus=_THREAD_STATUS_STARTED;
while(!pThread->IsFinishing())
{
if(!pThread->Step())
break;
Sleep(pThread->GetDelay());
}
pThread->Finish();
}
pThread->nStatus=_THREAD_STATUS_UNKNOWN;
return 0;
}
int cThread::Start(BOOL bSuspended, int StackSize)
{
if(IsStarted())
return false;
hThread=CreateThread(NULL,StackSize,Run,this,bSuspended?CREATE_SUSPENDED:0,&dwThreadId);
if(hThread)
{
if(bSuspended)
{
Suspended();
return true;
}
Starting();
while(IsStarting())
Sleep(70);
return true;
}
else
{
dwThreadId = 0;
nStatus=_THREAD_STATUS_UNKNOWN;
return false;
}
}
int cThread::Stop()
{
if(IsStoped())return false;
Resume();
Finishing();
while(IsStarted()&&IsFinishing())
Sleep(70);
nStatus = _THREAD_STATUS_UNKNOWN;
return true;
}
int cThread::Suspend()
{
if(IsSuspended()||IsStoped()) return false;
if(SuspendThread(hThread)==-1)
return false;
Suspended();
return true;
}
int cThread::Resume()
{
if(IsResumed()||IsStoped()) return false;
if(ResumeThread(hThread)==-1)
return false;
Resumed();
return true;
}
Пользуйтесь.
Возможно я переоцениваю важность данной идеи. Но мне эти строки спасли много нервов.
Чтобы пользоваться достаточно пронаследоваться и реализовать соответствующие члены-функции.