原子操作:简单的变量操作,加减、赋值、位与、位异或。
临界区:一个代码段的原子操作。
信号量:内核对象,用来限流,限制最大同时使用资源数。
互斥体:内核对象,线程拥有者概念,解决临界区内崩溃导致死锁问题。
事件:内核对象,没有拥有者概念,自由度高,可由程序员自己封装同步机制。
老师的说法 互斥体可以看作信号量的弱化版 ,经过实验证明不准确。
应该再补充一句,能实现 一个锁孔的信号量 的功能
信号量和临界区有一样的问题:保护的代码崩溃了,没有解锁,别的线程一样会死锁。
所以 临界区看作是信号量的弱化版 还行。
#include <Windows.h>
#include <iostream>
DWORD WINAPI ThreadProc1(LPVOID lpThreadParameter) {
HANDLE hSe = (HANDLE)lpThreadParameter;
printf("Thread1 - start\n");
WaitForSingleObject(hSe, -1);
ExitThread(0); // 假设线程崩溃 未释放信号量
ReleaseSemaphore(hSe, 1, NULL);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpThreadParameter) {
HANDLE hSe = (HANDLE)lpThreadParameter;
printf("Thread2 - start\n");
WaitForSingleObject(hSe, -1);
printf("Thread2 - semaphore\n");
ReleaseSemaphore(hSe, 1, NULL);
printf("Thread2 - end\n");
return 0;
}
int main()
{
// 创建信号量
HANDLE hSe = CreateSemaphore(NULL, 1, 1, NULL);
// 创建俩线程
DWORD dThreadId1 = 0;
HANDLE hThread1 = CreateThread(NULL, NULL, ThreadProc1, (LPVOID)hSe, NULL, &dThreadId1);
DWORD dThreadId2 = 0;
HANDLE hThread2 = CreateThread(NULL, NULL, ThreadProc2, (LPVOID)hSe, NULL, &dThreadId2);
printf("Good Drama Start\n");
getchar();
return 0;
}