What?
Multithreading is the capability of being able to utilise multiple threads of execution simultaneously in an application. In more basic words, it allows a program to do two things at once, hence the term multitasking. When an application is run, it is called a process and each of these processes contains at least one thread although this can be one of many concurrent threads that belong to that particular process.
Prior to Win32, the only type of multitasking that existed was a variety known as cooperative multitasking. This had some major disadvantages though, due to its reliance upon applications. It didn't have the concept of priorities, background processing or multithreading that are most prominent in a more modern variation of multitasking known as preemptive multitasking.
Preemptive multitasking exists in the majority of popular operating systems today, not only Windows. This method offers many advantages over the old model, perhaps the most important being the ability to allow higher priority tasks interrupt or preempt the system.
Why?
There may be a time that you would like to create an application that is able to perform more than one task at once, give it the capability to multitask. You may have encountered this before without even realising that very fact. A good example of this is a program that undertakes a CPU intensive function while constanting updating numbers in the GUI. If you have ever constructed an application similar to that (perhaps for geek ;]) you should have noticed that the interface appears to hang until the calculation is complete. Multithreading can solve this problem.
The following tasks can be achieved by utilising multiple threads:
Manage input for muliple windows.
Manage input from several devices.
Distinguish tasks of varying priority.
Allow the user interface to remain responsive, while allocating time to background tasks.
Although these issues can be overcome by using more than one process, it is often more efficient to use a single multithreaded application for the following reasons:
The system can perform a context switch more quickly for threads than processes, because a process has more overhead than a thread does (the process context is larger than the thread context).
All threads of a process share the same address space and can access the process's global variables, which can simplify communication between threads.
All threads of a process can share open handles to resources, such as files and pipes.
How?
The scheduler of Windows manages multitasking, giving each process a time slice according to the priority of that process (assuming that it only contains one thread). If a process contains multiple threads, each thread gets its own time slice relative to its priority. Windows has functions in the form of API calls that manipulate threads in multithreaded applications. Following is a brief summary of the most notable that are available to the programmer:
Creation
To create the thread itself, the CreateThread Win32 API call is used. This call takes six arguments, although only two are required, that being the address function in which to start the new thread and a variable in which to place the thread's ID. It follows the following structure:
CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId)
lpThreadAttributes : A pointer to a SECURITY_ATTRIBUTES structure. This can be null.
dwStackSize : Initial thread stack size. As the stack in threads grows dynamically, this can be zero. Alternate values can be used for optimization.
lpStartAdress : Address of the function to start the new thread's execution.
lpParameter : A single 32 bit parameter value passed to the thread. This can be null.
dwCreationFlags : Additional flags that control the creation of the thread, such as starting in a suspended state. This can be zero.
lpThreadId : A variable that receives the thread's identifier.
If the creation of the thread is successful, this function returns a handle to the new thread, otherwise null is returned.
Priority
Once the thread has been created and a handle to it received, its priority can then be set using the following API call:
SetThreadPriority(hThread, nPriority)
hThread : Identifies the thread whose priority value is to be set. This was returned by the CreateThread() call.
nPriory : Specifies the priority for the thread. Can be (from lowest to highest activity) THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL.
This function returns non-zero on success and zero on failure.
Suspend
This function allows the execution of the thread to be halted until ResumeThread() is called.
SuspendThread(hThread)
hThread : Handle of the thread
If the function succeeds, the return value is the thread's previous suspend count; otherwise, it is 0xFFFFFFFF.
Resume
This function resumes the execution of a thread after is has been halted by SuspendThread().
ResumeThread(hThread)
hThread : Handle of the thread
If the function succeeds, the return value is the thread's previous suspend count. If the function fails, the return value is 0xFFFFFFFF.
Terminate
This function is used when execution of the thread is to be terminated.
TerminateThread(hThread, dwExitCode)
hThread : Identifies the thread to terminate
dwExitCode : Specifies the exit code for the thread. Can be retrieved by the GetExitCodeThread() call.
If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.
By using the above API calls you should be able to create a thread, alter its priority and then terminate it. If you do not possess the knowledge of how to call Win32 API in your chosen language, then a quick google search should provide the answer. Multithreading is an extremely effective tool for a programmer to utilise and once mastered will enable an application to multitask and therefore be much more efficient and be able to provide continuous feedback to the user.