Introduction
There comes a time in every man's life when he has to survive a loop ! Let's say you want your user to select a folder and then you start scanning it for files . This can be a time consuming process and the user is not in the mood of seeing that the applications screen got ballistic . While searching he would like to be able to stop Search . This is a problem where we need multithreading or wisdom.
This is what wisdom says : Someone was asking how to continue processing messages for its application while working . That is a quite simple task . For those of you who used Visual Basic know of the life saving DoEvents()
function . Well this here is its implementation in C/C++ !
Wisdom : DoEvents()
BOOL DoEvents()
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (GetMessage(&msg, NULL, 0, 0) )
{
if((msg.message!=WM_DESTROY)&&(msg.message!=WM_CLOSE)&&
((msg.message!=WM_SYSCOMMAND)&&(msg.wParam!=SC_CLOSE)))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
return TRUE;
}
}
return 0;
}
And the Multi-Threading way :
What is a thread ! In technical terms Microsoft Says :
A thread is basically a path of execution through a program. It is also the smallest unit of execution that Win32 schedules. A thread consists of a stack, the state of the CPU registers, and an entry in the execution list of the system scheduler. Each thread shares all of the process�s resources. A process consists of one or more threads and the code, data, and other resources of a program in memory. Typical program resources are open files, semaphores, and dynamically allocated memory. A program executes when the system scheduler gives one of its threads execution control. The scheduler determines which threads should run and when they should run. Threads of lower priority may have to wait while higher priority threads complete their tasks. On multiprocessor machines, the scheduler can move individual threads to different processors to �balance� the CPU load. Each thread in a process operates independently. Unless you make them visible to each other, the threads execute individually and are unaware of the other threads in a process. Threads sharing common resources, however, must coordinate their work by using semaphores or another method of interprocess communication.
I say this :
Imagine a program like a house with usually one room - the main thread . In this room you can have you living room . You need a bath in case you want to take a bath or after one day of hard work , you come home exhausted . On your way to your house you imagine yourself in the hot water relaxing . Making plans you park your car in front of the house and then with a silly smile of happiness on your face you go in with only one intention : get deep underwater . You call your wife : "Dear I'm home !" , no answer ! You are even happier thinking : "She's gone ! I'm gonna have some relaxation time for my own ! " With a feeling of relief you go in your room and grab a towel . You take your clothes off and wrap the towel around yourself . You go in the kitchen get a glass , pour some wine and you start moving towards the final destination singing . You open the door and you are shocked! : "Holly cow woman . What are you doing here !?!?"
This is what threads are really all about , you reach the worst conclusion of building another bath (thread) so you can take bath (execute) even if someone else is doing that (running) at that certain moment . BUT wait our story didn't end this way . The wife says : Care to join me ? Now our man fills with wisdom and uses the first technique of message peeking . He gets to run in the first thread , along with his wife , and still processes all messages from outside !
while(kids_not_home)
{
take_hot_bath(wife_included);
}
This here is my thread class I wanted to share with you :
#if !defined(
AFX_THREAD_H__BC1E1A60_2C98_4D0F_BA79_C1156C9BFFC3__INCLUDED_)
#define AFX_THREAD_H__BC1E1A60_2C98_4D0F_BA79_C1156C9BFFC3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
#include <windows.h>
class CXThread
{
public:
unsigned long GetRunTime();
unsigned long GetExitCode();
bool IsOver();
bool IsRunning();
bool Terminate(unsigned long exitCode=0);
bool Suspend();
bool Resume();
bool Initiate(bool bSuspended=0);
CXThread();
virtual ~CXThread();
protected:
virtual void ExitInstance();
virtual void InitInstance();
virtual unsigned long ThreadFunction();
private:
static unsigned long __stdcall Watcher(void * lpVoid);
static unsigned long __stdcall ThreadBody(void * lpVoid);
HANDLE hTh,hwTh;
unsigned long wthID,thID,thsTime,theTime;
};
#endif
It's more than simple ! Now I think you want an example of some kind ! Go on reading.
Example
How to use each function :
#include "xthread.h"
class CDirSearch : public CDialog,CXThread
{
protected:
unsigned long ThreadFunction();
void ExitInstance();
void InitInstance();
unsigned long CDirSearch::ThreadFunction()
{
ListDirectory(dir,"*.*",subdirs);
return 1;
}
void CDirSearch::ExitInstance()
{
m_OK.EnableWindow(1);
}
void CDirSearch::InitInstance()
{
m_OK.EnableWindow(0);
}
History
- Only release 3:47 PM 3/15/2003 (I think)
Last but not least
And if you did not understand anything look at the code . You can't miss it . You'll get it for sure !:~) The source code will reveal its darkest secrets to your mortal eyes by only looking at it . And I'll let you in on another little secret of mine . You can use the very ancient but long forgotten copy-paste technique if the complexity of the source code overwhelms you . And if you need more information check the holy book of software engineers , the forbidden MSDN . Many words of wisdom will be discovered within its dirty and dusty pages . And to find out the truth about our existence , humanity , universe and aliens mail me tomkat@rol.ro