在windows下:
信号量(Semaphore)内核对象对线程的同步方式,它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。
CreateSemaphore()
OpenSemaphore()
ReleaseSemaphore(),
WaitForSingleObject()/WaitForMultipleObjects()
CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。
一般是将当前可用资源计数设置为最大资源计数,
每增加一个线程对共享资源的访问,当前可用资源计数就会减1,
只要当前可用资源计数是大于0的,就可以发出信号量信号。
但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。
线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。
说明如下:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
LONG lInitialCount, // 初始计数
LONG lMaximumCount, // 最大计数, 定义了允许的最大资源计数
LPCTSTR lpName // 对象名指针, 创建的信号量定义一个名字,其创建的是一个内核对象,因此在其他进程中可以通过该名字而得到此信号量
);
OpenSemaphore()函数即可用来根据信号量名打开在其他进程中创建的信号量,函数原型如下:
HANDLE OpenSemaphore(
DWORD dwDesiredAccess, // 访问标志
BOOL bInheritHandle, // 继承标志
LPCTSTR lpName // 信号量名
);
在线程离开对共享资源的处理时,通过ReleaseSemaphore()来增加当前可用资源计数。否则将会出现当前正在处理共享资源的实际线程数并没有达到要限制的数值,
而其他线程却因为当前可用资源计数为0而仍无法进入的情况。
BOOL ReleaseSemaphore(
HANDLE hSemaphore, // 信号量句柄
LONG lReleaseCount, // 计数递增数量
LPLONG lpPreviousCount // 先前计数,可以设置为NULL,
);
该函数将lReleaseCount中的值添加给信号量的当前资源计数,一般将lReleaseCount设置为1,
WaitForSingleObject和WaitForMultipleObjects主要用在试图进入共享资源的线程函数入口处,
主要用来判断信号量的当前可用资源计数是否允许本线程的进入。
只有在当前可用资源计数值大于0时,被监视的信号量内核对象才会得到通知。