Win32编程

4、线程同步机制

1、课程目标

  1. 理解线程同步的必要性
  2. 掌握各种同步对象的使用
  3. 学会选择合适的同步机制
  4. 理解死锁和避免方法

2、名词解释

术语英文说明
临界区Critical Section进程内的轻量级锁
互斥体Mutex跨进程的排他锁
信号量Semaphore控制资源访问数量
事件Event线程间的通知机制

3、使用工具

工具用途
Visual Studio Debugger线程调试
Process Explorer查看同步对象

4、代码实现

4.1、示例1:临界区

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

CRITICAL_SECTION g_cs;
int g_counter = 0;

DWORD WINAPI IncrementThread(LPVOID lpParam) {
    for (int i = 0; i < 100000; i++) {
        EnterCriticalSection(&g_cs);
        g_counter++;
        LeaveCriticalSection(&g_cs);
    }
    return 0;
}

void CriticalSectionDemo() {
    InitializeCriticalSection(&g_cs);
    
    HANDLE threads[4];
    for (int i = 0; i < 4; i++) {
        threads[i] = CreateThread(NULL, 0, IncrementThread, NULL, 0, NULL);
    }
    
    WaitForMultipleObjects(4, threads, TRUE, INFINITE);
    printf("Counter: %d (expected: 400000)\n", g_counter);
    
    for (int i = 0; i < 4; i++) CloseHandle(threads[i]);
    DeleteCriticalSection(&g_cs);
}

4.2、示例2:互斥体

HANDLE g_hMutex = NULL;

DWORD WINAPI MutexThread(LPVOID lpParam) {
    int id = (int)(size_t)lpParam;
    
    DWORD result = WaitForSingleObject(g_hMutex, 5000);
    if (result == WAIT_OBJECT_0) {
        printf("Thread %d: Acquired mutex\n", id);
        Sleep(1000);
        ReleaseMutex(g_hMutex);
    }
    return 0;
}

void MutexDemo() {
    g_hMutex = CreateMutex(NULL, FALSE, TEXT("MyMutex"));
    // 创建并等待线程...
    CloseHandle(g_hMutex);
}

4.3、示例3:信号量

HANDLE g_hSemaphore = NULL;

void SemaphoreDemo() {
    // 最多3个线程同时访问
    g_hSemaphore = CreateSemaphore(NULL, 3, 3, NULL);
    
    // 获取资源
    WaitForSingleObject(g_hSemaphore, INFINITE);
    // 使用资源...
    
    // 释放资源
    ReleaseSemaphore(g_hSemaphore, 1, NULL);
    
    CloseHandle(g_hSemaphore);
}

4.4、示例4:事件

HANDLE g_hEvent = NULL;

DWORD WINAPI WaiterThread(LPVOID lpParam) {
    printf("Waiting for event...\n");
    WaitForSingleObject(g_hEvent, INFINITE);
    printf("Event signaled!\n");
    return 0;
}

void EventDemo() {
    // 手动重置事件
    g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    HANDLE hThread = CreateThread(NULL, 0, WaiterThread, NULL, 0, NULL);
    
    Sleep(2000);
    SetEvent(g_hEvent);  // 触发事件
    
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(g_hEvent);
}

5、课后作业

  1. 基础练习:实现生产者-消费者模型
  2. 互斥体应用:使用互斥体实现单实例程序
  3. 信号量应用:实现连接池的并发控制
  4. 死锁分析:创建并分析一个死锁场景