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. 死锁分析:创建并分析一个死锁场景