windows下进程同步方式之一的信号量对象主要包含如下三个部分:
计数:标记使用该信号量的线程数
最大资源数据:信号量控制的最大资源的数目
可用资源数目:信号量当前可用的资源数目
可用资源数目如果大于0,表示信号量已被触发,如果等于0表示信号量未触发
函数接口
1. 创建信号量 CreateSemaphore()
HANDLE WINAPI CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性,通常为NULL
_In_ LONG lInitialCount, // 可用资源数目
_In_ LONG lMaximumCount, // 信号量对象可处理的最大资源数
_In_opt_ LPCTSTR lpName // 信号量的名称,进程之间可共享
);
2. 打开信号量 OpenSemaphore()
HANDLE WINAPI OpenSemaphore(
_In_ DWORD dwDesiredAccess, // 访问的权限
_In_ BOOL bInheritHandle, // 子进程继承信号量对象与否
_In_ LPCTSTR lpName // 信号量对象名称
);
3. 获取信号量对象 WaitForSingleObject()
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle, // 内核对象句柄
_In_ DWORD dwMilliseconds // 对象被触发前的等待时间,INFINITE表示阻塞等待
);
WaitForSingleObject被称呼为等待函数,是等待内核对象被触发通用的等待函数,
被用在所有的内核对象触发等待中。等待函数会检查信号量的当前资源使用计数,
如果大于0,表示信号量处于触发状态,那么等待函数会把资源使用计数器减1,并让调用线程继续执行。
信号量的最大优势就是在于以原子的方式来执行这些测试和设置操作。
如果等于0,表示信号量处于未触发状态,那么系统会让调用线程进入等待状态,直到被唤醒(当前资源计数大于0)
4. 释放信号量ReleaseSemaphore()
BOOL WINAPI ReleaseSemaphore(
_In_ HANDLE hSemaphore, // 信号量对象句柄
_In_ LONG lReleaseCount, // 释放使用的资源树
_Out_opt_ LPLONG lpPreviousCount // 一般设为null
);
当一个线程使用完信号量对象控制的有限资源后,应该调用ReleaseSemaphore,释放使用的资源,使信号量对象的当前资源计数得到恢复
5. 关闭句柄 CloseHandle()
BOOL WINAPI CloseHandle(
_In_ HANDLE hObject // 句柄
);
创建的内核对象,我们必须通过调用CloseHandle向系统表明结束使用内核对象。
如果传入的句柄有效,系统将获得内核对象数据结构的地址,并将结构中的使用计数减1,
如果使用计数0,就会将内核对象销毁,从内存空间中擦除