Threads in WinAPI
When application is starting to run, the process is created. Usually every program has one process.
For every process memory is allocated. Such memory is called - virtual address space. When we are looking at addresses of variables in debugger, we see address from virtual address space.
Threads
Every process has at least one thread. All our applications have been consisted of one process and one thread. In this tutorial we will know how to create additional threads in the process.
The most important question about threads: why do you need to have several threads in one application? Different threads could be running by different CPU cores. For example, in our single-threaded app one function process AI and other computes physics. In this case first will be processed one function, and then another. If we separate application in two threads and run it on two-core CPU, AI and physics will be processed simultaneously.
All threads has access to address space of the process. And this could be the problem. We will deal with it in future tutorials.
For C++ thread is just a function with a specific prototype. You can create thread with a function CreateThread.
Thread creation - CreateThread function
CreateThread function returns thread handle:
!1?HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );?1!1. lpThreadAttributes - this argument sets if created thread could be inherited by child process. We will not create child process, so set it to NULL.
2. dwStackSize - stack size in bytes. If you set it to 0, the default value will be used (1 megabyte).
3. lpStartAddress - function address, which will be executioned by the thread. This function is a thread. This function should have specific prototype. You can name this function as you want.
4. lpParameter - pointer to variable, which will be passed to the thread.
5. dwCreationFlags - creation flags. You can delay thread running here. We will run thread immediately, so set it to 0.
6. lpThreadId - pointer to variable where will be saved thread id. We don't need it, so set it to NULL.
Let's see at the CreateThread call:
!1?HANDLE thread = CreateThread(NULL,0,thread2,NULL, 0, NULL);?1!Here we saved thread handle in variable thread. Third argument is the address of the thread function. thread2 is the function name which will be second thread. Here it's code:
!1?DWORD WINAPI thread2(LPVOID t) { /* Second thread's code */ return 0; }?1!Thread function must correspond to this prototype:
!1?DWORD WINAPI ThreadProc(LPVOID lpParameter)?1!Argument of this function is passed by fourth parameter of CreateThread function. Without all type redefenitions, this prototype will be looked like this:
!1?unsigned long __stdcall ThreadProc(void* lpParameter)?1!At last let's see at example of second thread creation:
Application with two threads
You can download code of this app at the beginning of the tutorial. To use threads you need to include file windows.h. Let's see at the code:
!1?DWORD WINAPI thread2(LPVOID); int main() { cout << "First thread\n"; HANDLE thread = CreateThread(NULL,0,thread2,NULL, 0, NULL); cout << "More data from first thread\n"; for (int i = 0; i < 1000000; i++) {} cout << "Even more data from first thread\n"; _getch(); return 0; } DWORD WINAPI thread2(LPVOID t) { cout << "Second thread\n"; return 0; }?1!My app outputs in console this:

Firstly, text First thread is printed. Then second thread is created. But what will arrive next, you can't say for sure: More data from first thread or Second thread. It depends what thread will be faster to print it's message. In most cases first thread will be faster - second thread need time to allocate resources and call it's function.
After that I run empty for loop. While it's iterated, second thread have time to print Second thread message. After that the last message of first thread is printed.
Conclusion
In next tutorials I will introduce multithreaded applications. This allow us to learn specifics of it's work.
I hope, you get the main idea of work with threads.
P.S. In attached archive there are .exe file in release configuration. On my computer this version outputs all messages of the first thread before second's. Compiler successfully optimized empty for loop.