1、课程目标
- 理解线程同步的必要性
- 掌握各种同步对象的使用
- 学会选择合适的同步机制
- 理解死锁和避免方法
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、课后作业
- 基础练习:实现生产者-消费者模型
- 互斥体应用:使用互斥体实现单实例程序
- 信号量应用:实现连接池的并发控制
- 死锁分析:创建并分析一个死锁场景