信号量内核对象:(semaphore)对资源进行计数:最大资源计数(表示信号量控制的最大资源的数目)、当前资源计数(表示信号量当前可用的资源数目) 可用于进程和线程间同步 |
信号量规则:1.如果当前资源计数大于0,信号量处于触发状态 2.如果当前资源计数等于0,那么信号量处于未触发状态 |
|
HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD LONG lInitialCount, // initial count LONG lMaximumCount, // maximum count LPCT STRlpName// object name //有名字可用于进程同步 ); CreateSemaphore() lInitialCount:表示一开始可以使用的资源数目,即当前资源计数;lMaximumCount:信号量对象可以处理的最大资源数量 |
HANDLE OpenSemaphore( DWORDdwDesiredAccess, // access BOOLbInheritHandle, // inheritance option LPCTSTRlpName // object name ); dwDesiredAccess Integer,下述常数之一: SEMAPHORE_ALL_ACCESS (0x1F0003) 要求对事件对象的完全访问; [2] SEMAPHORE_MODIFY_STATE (0x0002) 允许使用ReleaseSemaphore函数; [2] SYNCHRONIZE (0x00100000L)允许同步使用信号机对象。 [2] bInheritHandle Integer,如果允许子进程继承句柄,则设为TRUE。 lpName String,指定要打开的对象的名字。//有名字可用于进程同步 |
WaitForSingleObject为等待函数,被用在所有的内核对象触发等待中。等待函数会检查信号量的当前资源使用计数,如果大于0,表示信号量处于触发状态,那么等待函数会把资源使用计数器减1,并让调用线程继续执行。如果等于0,表示信号量处于未触发状态,那么系统会让调用线程进入等待状态,直到被唤醒 |
BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount ); ReleaseSemaphore函数的作用是增加信号量的计数.即增加lReleaseCount个。 ReleaseSemaphore lReleaseCount:释放自己使用的资源数目,加到信号量的当前资源计数上,通常会传1. 当一个线程使用完信号量对象控制的有限资源后,应该调用ReleaseSemaphore,释放使用的资源,使信号量对象的当前资源计数得到恢复。 |
static HANDLE st_handleSemaphore = CreateSemaphore(NULL, 0,1, NULL);//第二参数为当前资源计数,为0表示信号量未触发状态 ,第3参数为最大资源数
bool CreateThreadSemaphore()
{
DWORD dwThreadId;
HANDLE HThread;
DWORD dwMainID = GetCurrentThreadId();
HThread = CreateThread(NULL, 0, SemaphoreThread, &dwMainID, CREATE_SUSPENDED, &dwThreadId);
ResumeThread(HThread);
Sleep(5000);
ReleaseSemaphore(st_handleSemaphore,1,NULL);//增加当前资源计数,使其>0,变成触发状态。
WaitForSingleObject(HThread, INFINITE);
CloseHandle(HThread);
qDebug() << "CreateThreadSemaphore quit!";
return true;
}
DWORD WINAPI SemaphoreThread(LPVOID lp)
{
while (WaitForSingleObject(st_handleSemaphore, 1000) != WAIT_OBJECT_0)
{
qDebug() << "SemaphoreThread is running!";
}
//要是等待函数发现信号量处于触发状态,返回WAIT_OBJECT_0,那么互斥量的可用资源计数减1.如果等于0,信号量处于未触发状态
Sleep(2000);
qDebug() << "SemaphoreThread quit!";
return 0;
}