当想让写入者线程和都去这线程以独占的方式或共享的方式访问一个资源的时候,可以使用SRWLock。在这些情况下,如果

都去这没有数据可以读取,那么它应该将锁释放并等待,直到写入者线程产生了新的数据为止。如果用来接收写入者线程的数据结构已满,那么写入者同样应该释放SRWLock并进入睡眠状态,直到读取这线程把数据结构清空为止。我们希望线程以原子的方式把锁释放并将自己阻塞,直到某一个条件成立为止。要实现这样的线程同步是比较复杂的。windows

BOOL WINAPI SleepConditionVariableCS(_Inout_ PCONDITION_VARIABLE ConditionVariable,_Inout_ PCRITICAL_SECTION   CriticalSection,_In_    DWORD               dwMilliseconds
);
BOOL  SleepConditionVariableSRW (    PCONDITION_VARIABLE ConditionVariable,    PSRWLOCK SRWLock,    DWORD dwMilliseconds,    ULONG Flags); 

提供了一种条件变量帮助我们完成这项工作。

当线程检测到相应的条件满足的时候(比如,由数据供读取者使用),他会调用WakeConditionVariable或WakeAllConditionVariable,

这样在Sleep*函数中的线程就会被唤醒。

实例:

#include"stdafx.h"
#include<windows.h>
#include<tchar.h>
#include<vector>
#include<iostream>
#include<process.h>
using namespace std;  DWORD WINAPI ThreadProduce(PVOID pvParam);
DWORD WINAPI ThreadUser1(PVOID pvParam);
DWORD WINAPI ThreadUser2(PVOID pvParam);  vector<int> ivec;  SRWLOCK g_lock;
SRWLOCK g_lock2;
CONDITION_VARIABLE g_ConditionVar;
RTL_CRITICAL_SECTION  g_csLock;
int _tmain()
{  InitializeSRWLock(&g_lock);  //初始化锁  InitializeCriticalSection(&g_csLock);InitializeConditionVariable(&g_ConditionVar) ;HANDLE hThread1 = (HANDLE)_beginthreadex(NULL,0,(unsigned int(_stdcall *)(void*))ThreadProduce,NULL,0,0);  HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(_stdcall *)(void*))ThreadUser1, NULL, 0, 0);  HANDLE hThread3 = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(_stdcall *)(void*))ThreadUser2, NULL, 0, 0);  /*  CloseHandle(hThread1);  CloseHandle(hThread2);  CloseHandle(hThread3);  */_gettchar();  return 0;
}
DWORD WINAPI ThreadProduce(PVOID pvParam)
{  for (int i = 0; i < 1000; i++)  {  EnterCriticalSection(&g_csLock);// Produce workivec.push_back(i);  LeaveCriticalSection(&g_csLock);// WakeConditionVariable(&g_condNotEmpty);//   AcquireSRWLockExclusive(&g_lock); //获得SRW锁  //    ReleaseSRWLockExclusive(&g_lock);//释放SRW锁  WakeConditionVariable(&g_ConditionVar);//因为每次执行完push_back后,容器里卖弄就会必定至少有一个元素(生产者)  //生产出东西了,这时候阻塞在Sleep*里面的线程就会被唤醒(读取者sleep线程)  Sleep(1);//停一下,让读取者先读  }  return 0;
}  DWORD WINAPI ThreadUser1(PVOID pvParam)
{  while (1)  {  EnterCriticalSection(&g_csLock); while (ivec.empty())  {  cout << "等待写入 1" << endl;  //如果容器是空的,也就是没有内容可以读,那么让线程进入睡眠状态,一直到调用WakeConditionAllVariable(&g_ConditionVar)  SleepConditionVariableCS(&g_ConditionVar,&g_csLock,INFINITE);  }  cout << "线程1:" << ivec.back() << endl;  ivec.pop_back();  LeaveCriticalSection(&g_csLock);}  return 0;
}
DWORD WINAPI ThreadUser2(LPVOID pvParam)
{  while (1)  {  EnterCriticalSection(&g_csLock);while (ivec.empty())  {  cout << "等待写入2"<<endl;  SleepConditionVariableCS(&g_ConditionVar, &g_csLock, INFINITE);  }  cout << "线程2:" << ivec.back() << endl;  ivec.pop_back();  LeaveCriticalSection(&g_csLock);}  return 0;
}  
#include"stdafx.h"
#include<windows.h>
#include<tchar.h>
#include<vector>
#include<iostream>
#include<process.h>
using namespace std;  DWORD WINAPI ThreadProduce(PVOID pvParam);
DWORD WINAPI ThreadUser1(PVOID pvParam);
DWORD WINAPI ThreadUser2(PVOID pvParam);  vector<int> ivec;  SRWLOCK g_lock;
SRWLOCK g_lock2;
CONDITION_VARIABLE g_ConditionVar;  int _tmain()
{  InitializeSRWLock(&g_lock);  //初始化锁  HANDLE hThread1 = (HANDLE)_beginthreadex(NULL,0,(unsigned int(_stdcall *)(void*))ThreadProduce,NULL,0,0);  HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(_stdcall *)(void*))ThreadUser1, NULL, 0, 0);  HANDLE hThread3 = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(_stdcall *)(void*))ThreadUser2, NULL, 0, 0);  CloseHandle(hThread1);  CloseHandle(hThread2);  CloseHandle(hThread3);  _gettchar();  return 0;
}
DWORD WINAPI ThreadProduce(PVOID pvParam)
{  for (int i = 0; i < 10000; i++)  {  AcquireSRWLockExclusive(&g_lock); //获得SRW锁  ivec.push_back(i);  ReleaseSRWLockExclusive(&g_lock);//释放SRW锁  WakeConditionVariable(&g_ConditionVar);//因为每次执行完push_back后,容器里卖弄就会必定至少有一个元素(生产者)  //生产出东西了,这时候阻塞在Sleep*里面的线程就会被唤醒(读取者sleep线程)  Sleep(1);//停一下,让读取者先读  }  return 0;
}  DWORD WINAPI ThreadUser1(PVOID pvParam)
{  while (1)  {  AcquireSRWLockExclusive(&g_lock);  while (ivec.empty())  {  cout << "等待写入" << endl;  //如果容器是空的,也就是没有内容可以读,那么让线程进入睡眠状态,一直到调用WakeConditionAllVariable(&g_ConditionVar)  SleepConditionVariableSRW(&g_ConditionVar,&g_lock,INFINITE,0);  }  cout << "线程1:" << ivec.back() << endl;  ivec.pop_back();  ReleaseSRWLockExclusive(&g_lock);  }  return 0;
}
DWORD WINAPI ThreadUser2(LPVOID pvParam)
{  while (1)  {  AcquireSRWLockExclusive(&g_lock);  while (ivec.empty())  {  cout << "等待写入2"<<endl;  SleepConditionVariableSRW(&g_ConditionVar, &g_lock, INFINITE, 0);  }  cout << "线程2:" << ivec.back() << endl;  ivec.pop_back();  ReleaseSRWLockExclusive(&g_lock);  }  return 0;
}

Windows核心编程条件变量相关推荐

  1. Windows核心编程之核心总结(第一章 错误处理)(2018.5.26)

    前沿 学习Windows核心编程是步入Windows编程殿堂的必经之路,2018年寒假重温了计算机操作系统知识,前阵子又过学习Windows程序设计方面的基础,正所谓打铁要乘热,所以我又入了Windo ...

  2. [笔记]Windows核心编程《十九》DLL基础

    系列文章目录 [笔记]Windows核心编程<一>错误处理.字符编码 [笔记]Windows核心编程<二>内核对象 [笔记]Windows核心编程<三>进程 [笔记 ...

  3. C++Windows核心编程读书笔记(转)

    http://www.makaidong.com/(马开东博客) 这篇笔记是我在读<windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的 ...

  4. [C++]《Windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

  5. 《windows核心编程系列》二谈谈ANSI和Unicode字符集

    第二章:字符和字符串处理 使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是 ...

  6. 窗口消息——Windows核心编程学习手札之二十六

    窗口消息 --Windows核心编程学习手札之二十六 Windows允许一个进程至多建立10000个不同类型的用户对象(user object):图符.光标.窗口类.菜单.加速键表等,当一个线程调用一 ...

  7. 未处理异常和C++异常——Windows核心编程学习手札之二十五

    未处理异常和C++异常 --Windows核心编程学习手札之二十五 当一个异常过滤器返回EXCEPTION_CONTINUE_SEARCH标识符时是告诉系统继续上溯调用树,寻找另外的异常过滤器,但当每 ...

  8. 结束处理程序——Windows核心编程学习手札之二十三

    结束处理程序 --Windows核心编程学习手札之二十三 使用SEH可以只关注程序要完成任务,而运行中发生的错误,系统将会发现并通知.Windows引入SHE是为了便于操作系统的开发,使用SHE所造成 ...

  9. 线程本地存储器——Windows核心编程学习手札之二十一

    线程本地存储器 --Windows核心编程学习手札之二十一 C/C++运行期库使用线程本地存储器,运行期库是在多线程应用程序出现前设计的,因此运行期库里的大多数函数是用于单线程应用程序的.函数strt ...

最新文章

  1. 一文了解卷积神经网络在股票中应用
  2. java初学者的书中收获
  3. Codeforces 999F Cards and Joy 【dp】【性质】
  4. php 判断radio选中哪个,jquery如何判断单选按钮radio是否选中
  5. python string转date类型_java string类型怎么转化成date类型
  6. 微服务实现不同登陆_PaaS与IaaS在微服务架构实现方面的6大不同
  7. C++ string split()和 replaceAll()
  8. mysql使用mybatis删除不生效_解决myBatis中删除条件的拼接问题
  9. CentOS 7.0 关闭防火墙
  10. 软件测试基础知识整理
  11. 小程序毕设作品之微信积分商城小程序毕业设计成品(7)中期检查报告
  12. css让全局字体为微软雅黑,wordpress主题通过自定义CSS实现全局更换微软雅黑字体...
  13. 好程序员web前端分享如何构建单页Web应用
  14. 端到端图像压缩《Checkerboard Context Model for Efficient Learned Image Compression》
  15. 一些常用意大利语 1000个单词
  16. RenderingNG中关键数据结构和它们的角色
  17. #1778. [Usaco2010 Hol]Dotp 驱逐猪猡(高斯消元)
  18. 信创办公–基于WPS的PPT最佳实践系列 (将幻灯片组织成节的形式)
  19. 一单一议让你头大?产品责任险的费率和报价全解析
  20. Barsetto百胜图BAV01咖啡机——办公室福利包怎么选?现磨咖啡解君愁

热门文章

  1. pytorch使用torch.nn.Sequential构建网络
  2. checkbox 选中_纯CSS修改checkbox复选框样式
  3. 温度补偿计算公式_钢材的基本计算公式(下)
  4. CAS客户端认证流程
  5. AT1219 歴史の研究 解题报告
  6. [No0000B3].NET C# 单体模式(Singleton)
  7. Android保存用户名和密码
  8. [洛谷2397]yyy loves Maths VI
  9. 求数组中各个元素的个数?
  10. 计划和跟踪工具 XPlanner