用户层的线程同步
1.原子操作
- 将一条语句转换成了具有同等功能的单条汇编指令 lock(指令前缀)
- 将代码内存锁定不让其他CPU同时读取这条代码,读取完后自动解锁
- 只能给单个整数类型(4/8)进行保护,不能使一段代码变成原子操作
- InterlockedIncrement 自增
- InterlockedExchange 交换两个数
2.临界区
- 多行代码的原子操作
- 一次只允许一个线程进入,直至线程离开
- 拥有线程拥有者的概念,同一个线程可以不断的重新进入临界区,但是进入了多少次,就要退出多少。
- 一旦拥有临界区的线程崩溃,那么所有等待临界区的线程就会产生死锁。
- 初始化: InitializeCriticalSection
- 保护:EnterCriticalSection 这两个函数之间的内容就是被保护的代码
- 结束保护 :LeaveCriticalSection
- 删除:DeleteCriticalSection
内核层的线程同步
事件,互斥体,信号量都是跨进程的,原理是挂起线程,性能不好
1.互斥体
- 拥有临界区的线程拥有者概念,但是线程崩溃不会死锁,执行较慢
- 创建:CreateMutex,如果第二个参数是FALSE,那么就是可等待
- 打开:OpenMutex
- 保护:WaitForSingleObject: 把互斥体置为不可等待
- 离开保护:ReleaseMutex把互斥体置为可等待
- 关闭:CloseHandle
2.事件
- 可以手动选择是否产生副作用,如果设置为手动状态,那么就不产生副作用,副作用的WaitForSingleObject后会改变激发态
- 创建:CreateEvent()
- 打开:OpenEvent()
- 保护:WaitForSingleObject()
- 设置为非激发态:ResetEvent()
- 退出(设置为激发态):SetEvent()
- 关闭:CloseHandle
3.信号量
- 有多把锁,可以控制活动线程的数量
- 创建:CreateSemaphore
- 打开:OpenSemaphore
- 上锁:WaitForSingleObject
- 解锁:ReleaseSemaphore
- 关闭:CloseHandle