Windows下进程/线程通信及同步总结

进程或线程中同步互斥手段

关键代码段

仅在进程内使用,用户态,速度快于内核对象。

事件对象 

特点:有激发状态(signaled)和未激发。可以分为手动和自动两种状态。可以跨进程使用。手动就是开发者必须显示的调用ResetEvent去将事件设置为无信号状态,那么如果一个有信号的事件对象,多个线程在等待的话,其实都可以继续执行;自动模式就是如果事件有信号,并且第一个等待线程获取了该信号,就会自动的设置为无信号,那么其他线程就会阻塞住,处于等待状态。 

CreateEvent : 创建或者打开事件对象,并返回句柄。如果存在,那么直接返回已有的句柄。

SetEvent : 设置为有信号

ResetEvent : 设置为无信号。一般都是手动模式使用的。自动事件对象是无需自己去维护这个状态的,wait函数会自动设置。

PulseEvent : 先设置为有信号,然后再设置为无信号。这是为了兼容而保留的,不建议使用。因为不确定会让多少线程继续执行。

OpenEvent : 获取一个有名字的事件对象句柄。

参考 : https://docs.microsoft.com/en-us/windows/win32/sync/using-event-objects

互斥量Mutex

特点:可以跨进程使用。仅一个线程拥有互斥量的访问权。signal状态表示当前没有线程拥有该对象。

CreateMutex : 创建互斥量,并选择是否拥有该互斥量。

OpenMutex : 打开一个具名的互斥量。

ReleaseMutex : 放弃指定互斥量的拥有权。

如果想要获取mutex的拥有权,那么需要使用wait函数,当然CreateMutex指定初始拥有也可以获取拥有权。

PS : 抛弃状态,abandoned 。需要说明这个状态,因为wait函数可能返回这个状态值,需要做一些处理。如果一个线程具有Mutex拥有权,但是结束时并没有释放拥有权,那么该互斥量处于抛弃状态,如果某个wait函数在等待该互斥量的话,那么会返回WAIT_ABANDONED。这个时候,被共享的资源处于一个不确定的状态了。

参考 : https://docs.microsoft.com/en-us/windows/win32/sync/mutex-objects

信号量Semaphore 

可以指定多个线程拥有访问权限。相当于是扩展的互斥量。互斥量是退化的信号量。

CreateSemaphore :  创建或者打开一个信号量。可以指定初始计数以及最大计数,也就是最多多少线程可以同时访问一段资源。

OpenSemephore : 打开一个已有的信号量。

ReleaseSemaphore : 释放信号量。计数+1.

wait函数可以减少计数。

PS : CloseHandle 和这里说的计数无关。这里的计数是当前还可以获取信号量的线程数。而CloseHandle是决定系统是否释放这个内核对象。对于所有Open的句柄,都需要CloseHandle。这样才能释放。

参考:https://docs.microsoft.com/en-us/windows/win32/sync/using-semaphore-objects

进程线程通信手段

COM

古老的手段,通过调用其他应用注册的组件,使用guid来创建对应的对象,来操作其他进程。

剪切板

常见的剪切板,包括一组API以及相应的消息。

WM_COPYDATA

类似于剪切板。

套接字

不用多说,socket必备的进程通信手段,可用于不同的计算机间通信。

文件映射

高效的本机IPC手段,将文件或者一段数据映射到各个进程的进程空间中。通过同步手段来达到数据完整性。进程A可以写入读取,进程B也可以。无法跨计算机。

邮槽

单方向的,并且跨计算机通信。可以实现广播。

DDE

古老技术,不多描述。

管道

双工的,跨计算机通信。