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;
}
相关推荐
钱栈up2 分钟前
从 macOS 切回 Windows,我用 5 个免费工具把 80% 操作习惯搬了回来
windows·macos·策略模式
Android小码家9 分钟前
Vehicle 实战 自定义属性+测试demo
java·c++·framework·vhal·vehicle
hetao173383710 分钟前
2026-10-19 hetao1733837 的刷题记录
c++·算法
夏虫不可与之言冰13 分钟前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网
辛苦才能26 分钟前
C++ 哈希表深度解析:删除为什么必须打标记,负载因子为什么卡 0.7
开发语言·数据结构·c++·算法
百事牛科技31 分钟前
从局部到整体:Excel限制功能的几种实用设置
windows·excel
miller-tsunami37 分钟前
STL简介&string相关知识点
开发语言·c++·string
坤坤子吖1 小时前
Linux 线程同步与互斥——互斥锁
linux·服务器·c++·笔记·学习
TDTC_XQ1 小时前
Linux网络编程accept的讲解
linux·服务器·c++
2601_949695591 小时前
3DM游戏运行库合集安装教程,缺少DLL文件这样修复
windows·游戏·电脑