Introduction
A thread is a path of execution. A process requires at least one thread. But, it may contain more then one thread. If the process is closed, all the threads in that process are killed automatically. When we create a thread in an application that is actually a secondary thread. In C or C++ the program entry point is main
or wmain
(Unicode version). In windows application the program starts in WinMain
or wWinMain
. When the program starts, the operating system creates the first thread. Because, Windows is a multitasking operating system.
Thread function
Thread function is like an ordinary function with long void
pointer parameter. We can pass any data through void
pointer data type.
A simple thread function looks like
ThreadFunction(LPVOID param)
{
......
.......
}
Thread Priorities
The thread priority controls the thread process priority. The thread priorities are following.
- Highest
THREAD_PRIORITY_HIGHEST
- Above Normal
THREAD_PRIORITY_ABOVE_NORMAL
- Normal
THREAD_PRIORITY_NORMAL
- Below Normal
THREAD_PRIORITY_BELOW_NORMAL
- Idle
THREAD_PRIORITY_IDLE
We set thread priority with the CreateThread
function. We get or set thread priorities in GetThreadPriority
and SetThreadPriority
Win32API functions or CWinThread
�s functions which we call freely in the code. The priority functions return a BOOL
value.
C Run Time Library Multithreading
_beginthread
_beginthreadex
_endthread
_endthreadex
All the above c run time library functions are in the process.h header file. Make sure the Microsoft Visual Studio project setting is as multithreaded DLL. The _beginthread
and _beginthreadex
functions are used to create threads in C run time library. But, these functions have some differences. The _beginthreadex
has some add ional parameters like security and thread address. When we create thread using _beginthread
we end the thread use _endthread
. The _endthread
closes thread handle automatically. But, if we use _endthreadex
we close the nthread
handle using CloseHandle
Win32 API function. The C Run Time Library contains the Thread Local Storage (TLS) internally. We can use thread local storage using API or Compiler specific code. The TlsAlloc
, TlsFree
, TlsGetValue
and TlsSetValue
are used to store thread specific data. Microsoft recommend that If you use _beginthread
functions for C run Time Library you can not use Win32 API like ExitThread
or CreateThread
. Because, if use that method it might result in deadlocks. _beginthread
uses multiple arguments in the thread creation. Our example program is a simple console based application. The user enters number of threads to create and then we execute each thread.
void ThreadProc(void *param);
int main()
{
int n;
int i;
int val = 0;
HANDLE handle;
printf("\t Thread Demo\n");
printf("Enter the number of threads : ");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
val = i;
handle = (HANDLE) _beginthread( ThreadProc,0,&val);
WaitForSingleObject(handle,INFINITE);
}
return 0;
}
void ThreadProc(void *param)
{
int h=*((int*)param);
printf("%d Thread is Running!\n",h);
_endthread();
}
The thread waits for completion of another thread using WaitForSingleObject
Win32 API function.
MFC Multithreaded
The CWinThread
is the base class for all thread operations. MFC supports two types of threads. These are User Interface Thread and Worker thread. The user interface thread is based on windows message. The worker thread runs in the background process. (Examples, search a file in the find window or communicate with web browser in the web server) . The CWinThread
supports both worker thread and User interface Threads. But, we will discuss only worker threads.
The MFC class hierarchy
CObject
CCmdTarget
CWinThread
CWinApp
In the above class hierarchy the CWinApp
application class is derived from CWinThread
. So, if we create a application the thread is also created. If we create a thread, that is a secondary thread. The mother class CObject
has some features like, Serialization support, Run time Class information and Debugging support. The derived class CWinThread
also has the same features. The most common useful data members and member functions are the following.
Data members
m_hThread
The current thread handle
m_bAutoDelete
Whether the thread has set to auto delete or not
m_nThreadID
The current thread ID
Data Functions:
CreateThread
Start the exec execution of thread
SuspendThread
Increment thread suspend count. When the resume thread occur only the thread resume.
ResumeThread
Resume the thread. Decrements the thread count stack
SetThreadPriority
Set thread priority ( LOW, BELOW LOW or HIGH)
GetThreadPriority
Get the thread Priority
Not all the member functions in MFC as class members. We can access some functions globally also. These functions begin with Afx. The AfxBeginThread
, AfxEndThread
are most widely useful functions in MFC thread. We create thread using AfxBeginThread
function. AfxBeginThread
Syntax:
CWinThread* AfxBeginThread( AFX_THREADPROC ThreadProc, LPVOID Param,
int nPriority = THREAD_PRIORITY_NORMAL,UINT nStackSize = 0,
DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
The ThreadProc
is first Parameter in AfxBeginThread
function. We use name of thread function in this parameter. We pass the void pointer arguments in this function. The return type in the function is UINT
. The other arguments in AfxBeginThread
are optional. The default thread priority is THREAD_PRIORITY_NORMAL
. We can change this any time using CwinThread
SetThreadPriority
function. We also get the thread priority.
The Thread terminates using AfxEndThread
. The AfxEndThread
has a Exit code argument list.
CwinThread *pThread = AfxBeginThread( ThreadFunction, &data);
UINT ThreadFunction(LPVOID param)
{
DWORD result =0 ;
AfxEndThread(exitCode);
return result;
}
Win32 Multithread
Win32 Thread created by CreateThread
function. The syntax in CreateThread
is following
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
We terminate thread using the following methods.
- use
TerminateThread
function
- use
ExitThread
function
- use
return
But, Advanced Windows by Jeffery Ritcher recommends us to use the return
method. TerminateThread
or ExitThread
function does not clear the Thread Stack properly. The GetThreadTimes
is used to find the thread�s run time. The GetCurrentThreadID
is to get current thread ID. The Sleep
function is to sleep a particular thread for so many milliseconds. Example Sleep (1000)
will sleep the thread for 1000 milliseconds. The SwithToThread
is to switch to other threads. The SuspendThread
is to wait until a call of resume Thread. The WaitForSingleObject
is to wait when a particular thread completes its work. The WaitForMultipleObject
is used for multiple events. These functions wait for following situations - Change notification, Console input, Event, Job, Mutex ,Process, Semaphore, Thread and Waitable timer.
Benefits of Threads
The multithreaded application uses CPU 100% effectively. When we create a process, it will take more memory space. The multithreaded application shares the same process memory space. Every thread contains stack. So, the thread takes up less memory usage compared to a Process. The process may or may not contain more threads. If you run two or more threads in a process, all the threads share the process address space.
References