MSDN Documentation

Home Search

Threads

This article provides an overview of creating and managing threads in Windows using the Win32 API.

Table of Contents

Creating Threads

Use CreateThread or _beginthreadex to start a new thread.

#include <windows.h>
#include <process.h>

unsigned __stdcall ThreadFunc(void* param)
{
    // Thread code here
    return 0;
}

int main()
{
    HANDLE hThread = (HANDLE)_beginthreadex(
        NULL,          // security
        0,             // stack size
        ThreadFunc,    // start address
        NULL,          // parameter
        0,             // creation flags
        NULL);         // thread identifier

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

Thread Procedure

The thread function must match the required signature and should avoid calling non‑thread‑safe CRT functions unless using _beginthreadex.

Synchronization Primitives

Windows provides several synchronization objects to coordinate thread execution:

PrimitiveHeaderTypical Use
Critical SectionWindows.hFast intra‑process lock
MutexWindows.hInter‑process synchronization
EventWindows.hSignaling between threads
SemaphoreWindows.hControl access to limited resources
SRW LockWindows.hLightweight reader/writer lock

Thread Lifecycle

The typical lifecycle includes:

  1. Creation – CreateThread or _beginthreadex
  2. Execution – runs the thread procedure
  3. Waiting – WaitForSingleObject, WaitForMultipleObjects
  4. Termination – thread exits or calls ExitThread
  5. Cleanup – CloseHandle on the thread handle

Best Practices

Sample: Producer‑Consumer Using Event

#include <windows.h>
#include <process.h>
#include <stdio.h>

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];
int count = 0;

HANDLE hProduceEvent;
HANDLE hConsumeEvent;
HANDLE hMutex;

unsigned __stdcall Producer(void*)
{
    for (int i = 0; i < 10; ++i)
    {
        WaitForSingleObject(hMutex, INFINITE);
        while (count == BUFFER_SIZE) // buffer full
            WaitForSingleObject(hConsumeEvent, INFINITE);
        buffer[count++] = i;
        printf("Produced %d\n", i);
        SetEvent(hProduceEvent);
        ReleaseMutex(hMutex);
        Sleep(100);
    }
    return 0;
}

unsigned __stdcall Consumer(void*)
{
    for (int i = 0; i < 10; ++i)
    {
        WaitForSingleObject(hMutex, INFINITE);
        while (count == 0) // buffer empty
            WaitForSingleObject(hProduceEvent, INFINITE);
        int val = buffer[--count];
        printf("Consumed %d\n", val);
        SetEvent(hConsumeEvent);
        ReleaseMutex(hMutex);
        Sleep(150);
    }
    return 0;
}

int main()
{
    hMutex = CreateMutex(NULL, FALSE, NULL);
    hProduceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    hConsumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    _beginthreadex(NULL, 0, Producer, NULL, 0, NULL);
    _beginthreadex(NULL, 0, Consumer, NULL, 0, NULL);

    Sleep(3000);
    CloseHandle(hMutex);
    CloseHandle(hProduceEvent);
    CloseHandle(hConsumeEvent);
    return 0;
}