Windows API Reference

Microsoft Docs - Developer Network

Synchronization

This section describes the Windows functions and structures used for synchronizing access to resources by multiple threads and processes.

Overview

In a multitasking operating system like Windows, multiple threads and processes can execute concurrently. To prevent data corruption and ensure predictable behavior, it's crucial to synchronize access to shared resources. This involves using synchronization primitives that allow threads to coordinate their actions.

Key Synchronization Objects

Core Functions

Creating and Opening Synchronization Objects

Waiting for Synchronization Objects

Releasing Synchronization Objects

Interlocked Operations

For simple operations like incrementing or decrementing a counter, atomic interlocked operations can be more efficient than using heavier synchronization primitives.

Example Usage

Here's a simplified example of using a mutex to protect a shared resource:


#include <windows.h>
#include <iostream>

HANDLE hMutex;
int sharedResource = 0;

DWORD WINAPI ThreadFunction(LPVOID lpParam) {
    // Wait for the mutex to be available
    WaitForSingleObject(hMutex, INFINITE);

    // Access the shared resource
    sharedResource++;
    std::cout << "Thread incremented resource to: " << sharedResource << std::endl;

    // Release the mutex
    ReleaseMutex(hMutex);

    return 0;
}

int main() {
    hMutex = CreateMutex(
        NULL,    // default security attributes
        FALSE,   // initially not owned
        NULL);   // unnamed mutex

    if (hMutex == NULL) {
        std::cerr << "CreateMutex error: " << GetLastError() << std::endl;
        return 1;
    }

    HANDLE hThread1 = CreateThread(
        NULL,       // default security attributes
        0,          // default stack size
        ThreadFunction, // function pointer
        NULL,       // argument for thread
        0,          // default creation flags
        NULL);      // thread identifier

    HANDLE hThread2 = CreateThread(
        NULL,       // default security attributes
        0,          // default stack size
        ThreadFunction, // function pointer
        NULL,       // argument for thread
        0,          // default creation flags
        NULL);      // thread identifier

    // Wait for threads to finish
    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);

    // Clean up
    CloseHandle(hThread1);
    CloseHandle(hThread2);
    CloseHandle(hMutex);

    return 0;
}
            

Note: Proper synchronization is critical for avoiding race conditions and deadlocks. Always carefully consider the locking strategy for your application.

Important: Incorrectly used synchronization primitives can lead to severe performance issues or program instability. Refer to the detailed documentation for each function.

Related Topics