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;
}
相关推荐
汉克老师2 小时前
GESP2026年6月认证C++二级( 第三部分编程题(1、完全平方数计数))精讲
c++·循环·枚举算法·gesp2级·平方数·逆向枚举·区间判断
wuminyu2 小时前
markword在高并发场景下变化剖析
java·linux·c语言·jvm·c++
星夜夏空992 小时前
C++学习(1) ——C与C++
c语言·c++·学习
love530love2 小时前
AI Agent + 本地 ComfyUI 无头模式实战:关闭 IDE 后 AI 独立重启并完成图文生成
ide·人工智能·windows·python·音视频·agent·devops
旖-旎2 小时前
QT界面优化(6)
开发语言·c++·qt
UP_Continue2 小时前
AutoCAD--图形命令和选项
c++·autopilot
零点零一2 小时前
QT 5升级到 Qt 6 使用 Clazy 检查将 C++ 应用程序移植到 Qt 6
开发语言·c++·qt
爱奥尼欧2 小时前
轻量级可扩展日志框架-异步日志与系统集成
开发语言·数据库·c++·学习
迷路爸爸1802 小时前
Python collections 入门+实战
windows·python·c#·collections·dict