Click here to Skip to main content
16,004,227 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: hovering Pin
locoone15-Nov-06 12:31
locoone15-Nov-06 12:31 
GeneralRe: hovering Pin
Steve Echols15-Nov-06 18:41
Steve Echols15-Nov-06 18:41 
GeneralRe: hovering Pin
locoone16-Nov-06 14:10
locoone16-Nov-06 14:10 
GeneralRe: hovering Pin
Hamid_RT14-Nov-06 18:48
Hamid_RT14-Nov-06 18:48 
GeneralRe: hovering Pin
Waldermort14-Nov-06 20:21
Waldermort14-Nov-06 20:21 
GeneralRe: hovering Pin
Bram van Kampen16-Nov-06 16:49
Bram van Kampen16-Nov-06 16:49 
QuestionEnabling CLR caused a failure in my MFC window Pin
earlgraham14-Nov-06 12:30
earlgraham14-Nov-06 12:30 
QuestionSimple and very useful thread class Pin
urid14-Nov-06 10:38
urid14-Nov-06 10:38 
Hello everybody.
This article i decided to write because i worked very much with threads.
I wrote some clases that has thread functionality untill
i wrote this class that satisfy me. In thread class i need simplity and compability in derrivations.
The issue i want to talk is destruction of derrived classes. All we know that construction is beginning from base class and finished in derrived classes from down to top, but destruction begins from top level derrivation to base thread class. The problem is that untill you do not rich destructor of base class the thread function still running and using the members of derrived classes. Commonly thread procedure is running untill base class do not stop it and it can be problem, because the top level derrived class did not exist anymore.
In my class if in derrived class you must free some resources in destructor, you can stop thread procedure in destructor and be sure that after releasing the resources no more calling to the memory will happend. It's very important point.
The using of class is very simple:
You must derrived your own class and implement only function Run , but do not make implementation in endless loop , because this function will be called in endless loop in base class thread procedure. In constructor of derrived class you can decide whether object can be suspended or not and what delay between calling to Runfunction will be made. Also the class has thread statuses that you can ask, like Suspended or Running or Exited, Thread ID Thread handle of created WinThread object.
In real time you can change sequence delay of calling to your Run function.
As i said it's very small and simple class that has not too much functionality, but if somebody needs small and simple thread class it can be useful.

I did not know how to add source code so i did it message body

Here BaseThread.h

<br />
#ifndef __D___BASE_THEAD_URU_DINKIN__20061107__<br />
#define __D___BASE_THEAD_URU_DINKIN__20061107__<br />
<br />
<br />
// CBaseThread<br />
//~~~~~~~~~~~~~~~~~~~~~<br />
// This class is base thread class that has possibility to be suspended. <br />
class CBaseThread : public CObject<br />
{<br />
		// Running state<br />
		//~~~~~~~~~~~~~~<br />
		enum ERunningState<br />
		{<br />
			e_Suspended,<br />
			e_Running,<br />
			e_Exited<br />
		};<br />
<br />
		// Members<br />
		//~~~~~~~~~~~<br />
		DECLARE_DYNAMIC(CBaseThread);<br />
<br />
		HANDLE					m_hThread;			// Handle to thread<br />
		UINT						m_nThread;			// Thread ID<br />
		ERunningState		m_eThreadState;	// Thread state<br />
		CWinThread*			m_opThread;			// WinThread object<br />
		HANDLE					m_hExitEvent;		// Event to signal that thread must exit<br />
		HANDLE					m_hPauseEvent;	// Event to signal that thread must be paused<br />
		LONG						m_iDelay;				// Sequence delay<br />
<br />
public:<br />
		// Constructors<br />
		//~~~~~~~~~~~~~<br />
<br />
		CBaseThread(LONG a_iDelay = 1000, bool a_bCanBePaused = false);<br />
		~CBaseThread();<br />
<br />
<br />
		// Get Functions<br />
		//~~~~~~~~~~~~~~<br />
private:<br />
		HANDLE				hThread()const;			// Handle to Thread<br />
		HANDLE				hExitEvent()const;	// Event to signal that thread must exit<br />
		HANDLE				hPauseEvent()const;	// Event to signal that thread must be paused<br />
		LONG					iDelay()const;			// Sequence delay<br />
<br />
public:<br />
		UINT					nThread() const;		// Thread ID<br />
		ERunningState	eThreadState()const;// Thread state<br />
<br />
		// Set Functions<br />
		//~~~~~~~~~~~~~~<br />
private:<br />
		void SetUserData( LPVOID a_pUserData );	// User data for thread oject<br />
public:<br />
		void SetDelay( LONG a_iDelay );					// Set sequence delay fpr calling to function run<br />
		<br />
		// Virtual Functions<br />
		//~~~~~~~~~~~~~~~~~~<br />
protected:		<br />
		virtual void Run() = 0;		// Must be overriden in derrived classes<br />
<br />
<br />
		// Operations<br />
		//~~~~~~~~~~~<br />
<br />
public:<br />
		bool Create(int a_iPriority = THREAD_PRIORITY_NORMAL); // Create thread object<br />
		void Stop();				// Stop thread<br />
		void Suspend();			// Suspend the thread<br />
		void Resume();			// Resume the thread<br />
<br />
		// Static function<br />
		//~~~~~~~~~~~~~~~~<br />
private:<br />
		static UINT __cdecl ThreadHelper(LPVOID a_pUserData);<br />
<br />
};<br />
<br />
<br />
// Inline Function<br />
//~~~~~~~~~~~~~~~~~<br />
<br />
<br />
<br />
inline HANDLE	<br />
CBaseThread::hThread()const	<br />
// Brief:	Handle of thread object<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{ <br />
		if( m_opThread == NULL ) return NULL;<br />
		return m_opThread->m_hThread; <br />
}<br />
<br />
<br />
inline UINT		<br />
CBaseThread::nThread() const		<br />
// Brief:	Thread ID<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{ <br />
		if( m_opThread ) return -1;<br />
		return m_opThread->m_nThreadID; <br />
}<br />
<br />
<br />
inline CBaseThread::ERunningState	<br />
CBaseThread::eThreadState()const<br />
// Brief:	Thread state<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		return m_eThreadState;<br />
}<br />
<br />
<br />
inline HANDLE	<br />
CBaseThread::hExitEvent()const<br />
// Brief:	Event to signal that thread must exit<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		return m_hExitEvent;<br />
}<br />
<br />
inline HANDLE				<br />
CBaseThread::hPauseEvent()const<br />
// Brief:	Event to signal that thread must be paused<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		return m_hPauseEvent;<br />
}<br />
<br />
inline LONG					<br />
CBaseThread::iDelay()const<br />
// Brief:	Sequence delay fpr calling to function 'Run'<br />
// Get:		-<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
// Sequence delay<br />
{<br />
		return m_iDelay;<br />
}<br />
<br />
<br />
inline void					<br />
CBaseThread::SetDelay(LONG a_iDelay)<br />
// Brief:	Set sequence delay fpr calling to function 'Run'<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		m_iDelay = a_iDelay;<br />
}<br />
<br />
#endif<br />


And here is the BaseThread.cpp

<br />
#include "StdAfx.h"<br />
#include "basethread.h"<br />
<br />
<br />
IMPLEMENT_DYNAMIC(CBaseThread, CObject)<br />
CBaseThread::CBaseThread(LONG a_iDelay , bool a_bCanBePaused ) : CObject()<br />
// Brief:	Constructor<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		m_hThread = NULL;<br />
		m_nThread = 0;<br />
		m_eThreadState = e_Running;<br />
		m_opThread = NULL;<br />
		m_hExitEvent = NULL;<br />
		m_hPauseEvent = NULL;<br />
		m_iDelay = a_iDelay;<br />
<br />
		if( a_bCanBePaused )<br />
		{<br />
			m_hPauseEvent = CreateEvent( NULL, FALSE, FALSE, NULL );<br />
		}<br />
		m_hExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );<br />
<br />
}<br />
<br />
<br />
CBaseThread::~CBaseThread()<br />
// Brief:	Destructor<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		if( eThreadState() != e_Exited )<br />
		{<br />
			Stop();<br />
		}<br />
<br />
		if( m_hExitEvent )<br />
		{<br />
			CloseHandle( m_hExitEvent );<br />
		}<br />
<br />
		if( m_hPauseEvent )<br />
		{<br />
			CloseHandle( m_hPauseEvent );<br />
		}<br />
}<br />
<br />
<br />
bool <br />
CBaseThread::Create(int a_iPriority)<br />
// Brief: Create thread object<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		ASSERT( m_opThread == NULL );<br />
		m_opThread = AfxBeginThread(ThreadHelper, (LPVOID)this, a_iPriority );<br />
		return m_opThread == NULL ? false: true;<br />
}<br />
<br />
<br />
void <br />
CBaseThread::Stop()<br />
// Brief:	Stop thread and exit thread procedure<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		SetEvent( m_hExitEvent );<br />
		if( m_hPauseEvent != NULL )<br />
		{<br />
			SetEvent( m_hPauseEvent );<br />
		}<br />
<br />
		while( eThreadState() != e_Exited );<br />
}<br />
<br />
<br />
void <br />
CBaseThread::Suspend() <br />
// Brief:	Suspend the thread<br />
// Get:		-<br />
// Pre:		The thread must be in running mode<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		if( eThreadState() != e_Running ) return;<br />
		ASSERT( m_hPauseEvent != NULL );<br />
		ResetEvent( m_hPauseEvent );<br />
		m_eThreadState = e_Suspended;<br />
}<br />
<br />
void <br />
CBaseThread::Resume()<br />
// Brief:	Resume the thread<br />
// Get:		-<br />
// Pre:		The thread must be in suspended mode<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		if( eThreadState() != e_Suspended ) return;<br />
		ASSERT( m_hPauseEvent != NULL );<br />
		SetEvent( m_hPauseEvent );<br />
		m_eThreadState = e_Running;<br />
}<br />
<br />
<br />
UINT __cdecl <br />
CBaseThread::ThreadHelper(LPVOID a_pUserData)<br />
// Brief:	Thread main procedure, where called the derived class function<br />
// Get:		-<br />
// Pre:		-<br />
// Post:	-<br />
// Return:-<br />
// Method:Trivial<br />
{<br />
		CBaseThread* l_pThis = (CBaseThread*)(a_pUserData);<br />
		LONG l_iDelay = GetTickCount();<br />
		do<br />
		{<br />
			l_iDelay = GetTickCount();<br />
			if( l_pThis->eThreadState() == e_Suspended && l_pThis->hPauseEvent() != NULL )<br />
			// Check if we in suspend mode<br />
			{<br />
				WaitForSingleObject(l_pThis->hPauseEvent(), INFINITE) ;<br />
			}<br />
<br />
			if( l_pThis->eThreadState() == e_Running )<br />
			// Call to implemented function<br />
			{<br />
				l_pThis->Run();<br />
			}<br />
		}<br />
		while( WaitForSingleObject( l_pThis->hExitEvent(), l_pThis->iDelay()) == WAIT_TIMEOUT );<br />
		l_pThis->m_opThread = NULL;<br />
		l_pThis->m_eThreadState = e_Exited;<br />
		return 0;<br />
}<br />

AnswerRe: Simple and very useful thread class Pin
Maximilien14-Nov-06 11:14
Maximilien14-Nov-06 11:14 
AnswerRe: Simple and very useful thread class Pin
Zac Howland14-Nov-06 11:32
Zac Howland14-Nov-06 11:32 
QuestionDynamic menu Pin
Fraticiu Dan14-Nov-06 9:25
Fraticiu Dan14-Nov-06 9:25 
AnswerRe: Dynamic menu Pin
Steve Echols14-Nov-06 12:47
Steve Echols14-Nov-06 12:47 
GeneralRe: Dynamic menu Pin
Fraticiu Dan14-Nov-06 21:08
Fraticiu Dan14-Nov-06 21:08 
Questionfree zipper in c for zipping strings Pin
sknobli14-Nov-06 9:04
sknobli14-Nov-06 9:04 
AnswerRe: free zipper in c for zipping strings [modified] Pin
Waldermort14-Nov-06 9:12
Waldermort14-Nov-06 9:12 
GeneralRe: free zipper in c for zipping strings Pin
Chris Losinger14-Nov-06 10:14
professionalChris Losinger14-Nov-06 10:14 
GeneralRe: free zipper in c for zipping strings Pin
El Corazon14-Nov-06 10:46
El Corazon14-Nov-06 10:46 
AnswerRe: free zipper in c for zipping strings Pin
El Corazon14-Nov-06 10:52
El Corazon14-Nov-06 10:52 
GeneralRe: free zipper in c for zipping strings Pin
Chris Losinger14-Nov-06 11:11
professionalChris Losinger14-Nov-06 11:11 
GeneralRe: free zipper in c for zipping strings Pin
Jörgen Sigvardsson14-Nov-06 13:39
Jörgen Sigvardsson14-Nov-06 13:39 
AnswerRe: free zipper in c for zipping strings Pin
Hamid_RT14-Nov-06 18:58
Hamid_RT14-Nov-06 18:58 
AnswerRe: free zipper in c for zipping strings Pin
sknobli19-Nov-06 5:32
sknobli19-Nov-06 5:32 
QuestionFont Information Pin
Gupta Suraj14-Nov-06 8:09
Gupta Suraj14-Nov-06 8:09 
AnswerRe: Font Information Pin
Rajesh R Subramanian15-Nov-06 0:48
professionalRajesh R Subramanian15-Nov-06 0:48 
Questionhyperthreading a driver Pin
vineeshV14-Nov-06 7:06
vineeshV14-Nov-06 7:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.