windows原生条件变量支持

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

cpp 复制代码
#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;
}
相关推荐
旖旎夜光6 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
汉字萌萌哒6 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
走,带你去玩6 小时前
windows电脑 trae对接lanhu-mcp
windows
hy.z_7777 小时前
【C++】13. 继承
c++
汉字萌萌哒7 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
2401_890603407 小时前
C++ 继承
c++
果果燕8 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++
老洋葱Mr_Onion9 小时前
【C++】信息学奥赛CSP通关之路——CSP-J/S第一轮原创全真模拟试卷集(2026)卷四全卷解析
开发语言·c++
布莱克6059 小时前
理解 C/C++ 中的 void* 指针
c语言·c++
小小龙学IT11 小时前
simdjson:利用 SIMD 指令实现 GB/s 级 JSON 解析的 C++ 开源库
开发语言·c++·json