Condition Variable
为实现近点的生产者消费者问题。我们可以使用两个CONDITION_VARIABLE:g_full,g_empty来实现。在缓冲区满的时候,生产者线程调用SleepConditionVariableSRW(&g_full, &g_lock, INFINITE, 0)施放获得的锁并等待g_full。缓冲区空的时候,消费者可以调用leepConditionVariableSRW(&g_empty, &g_lock, INFINITE, 0)施放获得的锁并等待g_empty。掉进满足后,可是使用WakeAllConditionVariable唤醒所有等待的线程或者使用WakeConditionVariable唤醒一个等待的线程。
和Condition Variable配置使用的可以使CrticalSection也可以使SRWLock。
BOOL SleepConditionVariableCS(
PCONDITION_VARIABLE pConditionVariable,
PCRITICAL_SECTION pCriticalSection,
DWORD dwMilliseconds);
BOOL SleepConditionVariableSRW(
PCONDITION_VARIABLE pConditionVariable,
PSRWLOCK pSRWLock,
DWORD dwMilliseconds,
ULONG Flags);
参数dwMilliseconds指定等待超时的时间,如果超时方法返回FASLE;INFINITE指定等待不超时。参数Flags指定被唤醒时尝试获得的锁的类型。CONDITION_VARIABLE_LOCKMODE_ SHARED指定获得共享锁或者0指定获得独占锁。
const int MAX_SIZE = 10;
CONDITION_VARIABLE g_full;
CONDITION_VARIABLE g_empty;
SRWLOCK g_lock;
list<Product> products;
unsigned int WINAPI ProduceThreadFunc(void* pvParam)
{
int i(0);
while(true)
{
Sleep(rand() % 100);
AcquireSRWLockExclusive(&g_lock);
if (products.size() >= MAX_SIZE)
{
SleepConditionVariableSRW(&g_full, &g_lock, INFINITE, 0);
}
else
{
cout <<"Produce Product:" <<i <<" by thread " <<GetThreadId(GetCurrentThread()) <<endl;
products.push_back(Product(i++));
}
WakeAllConditionVariable(&g_empty);
ReleaseSRWLockExclusive(&g_lock);
}
return 0;
}
unsigned int WINAPI ConsumeThreadFunc(void* pvParam)
{
while(true)
{
Sleep(rand() % 100);
AcquireSRWLockExclusive(&g_lock);
if(products.size() == 0)
{
SleepConditionVariableSRW(&g_empty, &g_lock, INFINITE, 0);
}
else
{
Product p = products.front();
products.pop_front();
cout <<"Consume Product:" <<p.m_no <<" by thread " <<GetThreadId(GetCurrentThread()) <<endl;
}
WakeAllConditionVariable(&g_full);
ReleaseSRWLockExclusive(&g_lock);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
srand((unsigned)time(NULL));
InitializeSRWLock(&g_lock);
unsigned int threadId;
HANDLE thread1 = (HANDLE)_beginthreadex(NULL, 0, ProduceThreadFunc, NULL, 0, &threadId);
HANDLE thread2 = (HANDLE)_beginthreadex(NULL, 0, ConsumeThreadFunc, NULL, 0, &threadId);
HANDLE thread3 = (HANDLE)_beginthreadex(NULL, 0, ConsumeThreadFunc, NULL, 0, &threadId);
WaitForSingleObject(thread1, INFINITE);
WaitForSingleObject(thread2, INFINITE);
WaitForSingleObject(thread3, INFINITE);
system("pause");
return 0;
}