Threading in Windows

Overview

Threading enables an application to perform multiple operations concurrently. Windows provides several APIs for creating, managing, and synchronizing threads.

// Simple thread example (C++)
#include <windows.h>

DWORD WINAPI MyThread(LPVOID lpParam) {
    // Thread work here
    return 0;
}

int main() {
    HANDLE hThread = CreateThread(
        nullptr, 0, MyThread, nullptr, 0, nullptr);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

Creating Threads

Use CreateThread or the higher‑level _beginthreadex for C/C++ projects. In .NET, employ System.Threading.Thread.

// .NET example (C#)
using System;
using System.Threading;

class Program {
    static void Main() {
        Thread t = new Thread(DoWork);
        t.Start();
        t.Join();
    }

    static void DoWork() {
        Console.WriteLine("Running in a separate thread");
    }
}

Thread Pool

The Windows thread pool reduces overhead by reusing threads. In native code, call QueueUserWorkItem. In .NET, use ThreadPool.QueueUserWorkItem or Task APIs.

// Using the native thread pool
#include <windows.h>

VOID CALLBACK WorkItem(PTP_CALLBACK_INSTANCE, PVOID, PTP_WORK) {
    // Work to be done
}

int main() {
    PTP_WORK work = CreateThreadpoolWork(WorkItem, nullptr, nullptr);
    SubmitThreadpoolWork(work);
    WaitForThreadpoolWorkCallbacks(work, FALSE);
    CloseThreadpoolWork(work);
    return 0;
}

Synchronization

Synchronize access to shared resources using critical sections, mutexes, events, or slim reader/writer locks.

// Critical Section example
CRITICAL_SECTION cs;

void Init() {
    InitializeCriticalSection(&cs);
}

void ThreadSafeFunction() {
    EnterCriticalSection(&cs);
    // protected code
    LeaveCriticalSection(&cs);
}

Best Practices

  • Prefer the thread pool over manual thread creation for short tasks.
  • Keep critical sections short to avoid contention.
  • Use WaitableTimer for timed operations instead of busy loops.
  • Always release handles and resources.