Windows线程间/进程通信的方式

Windows线程/进程间通信的方式

 STL不支持线程安全

原子访问

同一时刻只允许一个线程访问资源(变量)

InterlockDecrement(); // 将变量-1, 同一个时刻只允许一个线程执行

volatile:防止编译器优化, 从内存中读取数据

int i = 10;
int j = i;
int k = i;

优化:将 i 的值放在寄存器中, 通过寄存器直接赋值

如果有其他线程在内存中改变了 i 的值, 将会出错。

 

关键段(临界区)

用户模式下的线程同步, 无法跨进程使用

同一时刻允许一个线程访问代码段

CRITICAL_SECTION : 类型
initializeCriticalsection(); // 初始化
DeleteCriticalSection(); // 释放
EnterCriticalSection(); // 进入关键段
LeaveCriticalSection(); // 离开关键段

随机选择一个等待线程进入关键段

实现方式

直接阻塞

旋转锁:尝试一段时间后再进入阻塞状态

异步:如果无法进入可以选择其他工作

TryEnterCriticalSection(); // 尝试进入关键段

 

如果使用关键段的线程被杀死, 会进入死锁状态。

在用户模式下使用, 效率较高

互斥量

内核对象, 可以跨进程

HANDLE : 类型
CreateMutex(); // 创建互斥量, 如果不跨进程, 名字设置为NULL
CloseHandle(); // 关闭内核对象
WaitForSingalObject(); // 等待, 可以设置等待时间
ReleaseMutex(); // 释放

 

如果使用互斥量的线程结束, 会释放锁。

需要切换内核和用户模式, 效率较低。

事件

内核对象

HANDLE : 事件的类型, 是内核对象
CreateEvent(); // 创建事件, 人工事件:手动重置, 自动事件:自动重置
WaitForSingalObject(); // 等待事件
SetEvent(); // 将事件置为有信号

 

信号量

内核对象

CreateSemaphore(); // 创建信号量
WaitForSingalObject(); // 等待
ReleaseSemaphore(); // 释放信号量, 单次释放的信号量个数不允许超过最大的信号量个数
CloseHandle(); // 关闭句柄

 

posted @ 2020-08-16 20:31  x_Aaron  阅读(267)  评论(0)    收藏  举报