windows原生条件变量支持

在windows vista 及后续的版本(Win7,Win8,Win10,Win11)中提供了对条件变量的原生支持(2006.11),为多线程程序开发带来便利。

#include <Windows.h> #include <iostream> #include <list> SRWLOCK myRwLock = SRWLOCK_INIT; CRITICAL_SECTION myCriticalSection; CONDITION_VARIABLE myConditionVar; class Task; std::list<Task*> tasks; class Task { public: Task(int taskID) { this->taskID = taskID; } void doTask() { std::cout << "handle a task, taskID: " << taskID << ", threadID: " << GetCurrentThreadId() << std::endl; } private: int taskID; }; DWORD WINAPI consumerThread(LPVOID param) { Task* pTask = NULL; while (true) { //AcquireSRWLockExclusive(&myRwLock); EnterCriticalSection(&myCriticalSection);//进入临界区 while (tasks.empty()) { //SleepConditionVariableSRW(&myConditionVar, &myRwLock, INFINITE, 0);//Flag 0:Exclusive 1:Shared,等待期间释放锁,退出等待时再次加锁 SleepConditionVariableCS(&myConditionVar, &myCriticalSection, INFINITE); //等待期间离开临界区,退出等待时再次进入临界区 } pTask = tasks.front(); tasks.pop_front(); LeaveCriticalSection(&myCriticalSection); //ReleaseSRWLockExclusive(&myRwLock); if (pTask == NULL) continue; pTask->doTask(); delete pTask; pTask = NULL; } return 0; } DWORD WINAPI producerThread(LPVOID param) { int taskID = 0; Task* pTask = NULL; while (true) { pTask = new Task(taskID); //AcquireSRWLockExclusive(&myRwLock); EnterCriticalSection(&myCriticalSection);//进入临界区 tasks.push_back(pTask); std::cout << "produce a task, taskID: " << taskID << ", threadID: " << GetCurrentThreadId() << std::endl; LeaveCriticalSection(&myCriticalSection);//离开临界区 //ReleaseSRWLockExclusive(&myRwLock); WakeConditionVariable(&myConditionVar); taskID++; //休眠1秒 Sleep(1000); } return 0; } int main() { //初始化读写锁,也可以用读写锁配合条件变量使用 //InitializeSRWLock(&myRwLock); //初始化临界区,本例使用临界区搭配条件变量 InitializeCriticalSection(&myCriticalSection); //初始化条件变量 InitializeConditionVariable(&myConditionVar); //创建5个消费者线程 HANDLE consumerThreadHandles[5]; for (int i = 0; i < 5; ++i) consumerThreadHandles[i] = CreateThread(NULL, 0, consumerThread, NULL, 0, NULL); //创建一个生产者线程 HANDLE producerThreadHandle = CreateThread(NULL, 0, producerThread, NULL, 0, NULL); //等待生产者线程退出 WaitForSingleObject(producerThreadHandle, INFINITE); //等待消费者线程退出 for (int i = 0; i < 5; ++i) WaitForSingleObject(consumerThreadHandles[i], INFINITE); DeleteCriticalSection(&myCriticalSection); return 0; }