条件变量是什么?

是一种同步对象。

条件变量有什么用?

用于复杂的、多线程的、多核的程序中,实现多个线程间同步任务。

条件变量与其它同步对象的区别?

与事件、互斥锁、segment等同步对象相比,条件变量最大的不同在于”条件“二字,其它同步对象的同步”条件“是固定的,如事件的被激发,互斥锁被释放,而条件变量的"条件"是完全自定义的,比如你可以实现当”张三赚了5块钱、李四在看电视、奥巴马访问马尔它“时,条件变量完成同步。所以说条件变量可用于复杂的同步任务。

Windows下有没有条件变量?

简单的答案是:没有,Windows API没有提供条件变量对象,这就是本文会存在的原因和要解决的问题。

复杂点的答案是:

使用Windows Vista之后的版本(Vista之后的版本提供了native的条件变量对象;

从开源库中抽取;

你可以自已实现;

方案1不现实,因为现阶段你的客户大多数还是使用windows xp/2003以下的版本,而且Vista卖的也并不好;

方案2可以参考ace库,不过太多条件宏和不相关代码,难以抽取使用(你不可能为了一个同步变量,而扯进整个庞大的ace库吧);

方案3难度更大,必须要熟悉多线程编程,还要考虑很多变态的细节;

我就是采用方案3 -- 自已实现的。因为网上没有现成的,不得已而为之!而你就不必重新造轮子,直接copy下面的代码到你的项目里就可以直接使用了(只要你的项目是C++的)。

实现代码如下:

class my_mutex

{

public:

my_mutex (bool be_initial_owner = false)

{

mutex_ = CreateMutexA (NULL, be_initial_owner, NULL);

}

~my_mutex (void)

{

CloseHandle (mutex_);

}

public:

int acquire (void)

{

DWORD ret = WaitForSingleObject (mutex_, INFINITE);

return ret == WAIT_OBJECT_0 ? 0 : -1;

}

int release (void)

{

BOOL bret = ReleaseMutex (mutex_);

return bret ? 0 : -1;

}

HANDLE handle (void)

{

return mutex_;

}

protected:

HANDLE mutex_;

};

class my_semaphore

{

public:

my_semaphore (long init_count, long max_count = (std::numeric_limits::max)())

{

assert (init_count >= 0 && max_count > 0 && init_count <= max_count);

sema_ = CreateSemaphoreA (NULL, init_count, max_count, NULL);

}

~my_semaphore (void)

{

CloseHandle (sema_);

}

public:

int post (long count = 1)

{

BOOL bret = ReleaseSemaphore (sema_, count, NULL);

return bret ? 0 : -1;

}

int wait (long timeout = -1)

{

DWORD ret = WaitForSingleObject (sema_, timeout);

return ret == WAIT_OBJECT_0 ? 0 : -1;

}

HANDLE handle (void)

{

return sema_;

}

protected:

HANDLE sema_;

};

template

class my_condition

{

public:

my_condition (MUTEX &m)

: mutex_ (m), waiters_ (0), sema_ (0)

{}

~my_condition (void)

{}

public:

/// Returns a reference to the underlying mutex_;

MUTEX &mutex (void)

{

return mutex_;

}

/// Signal one waiting thread.

int signal (void)

{

// must hold the external mutex before enter

if ( waiters_ > 0 )

sema_.post ();

return 0;

}

/// Signal *all* waiting threads.

int broadcast (void)

{

// must hold the external mutex before enter

if ( waiters_ > 0 )

sema_.post (waiters_);

return 0;

}

int wait (unsigned long wait_time = -1)

{

// must hold the external mutex before enter

int ret = 0;

waiters_++;

ret = SignalObjectAndWait (mutex_.handle (), sema_.handle (), wait_time, FALSE);

mutex_.acquire ();

waiters_ --;

return ret == WAIT_OBJECT_0 ? 0 : -1;

}

protected:

MUTEX &mutex_;

/// Number of waiting threads.

long waiters_;

/// Queue up threads waiting for the condition to become signaled.

my_semaphore sema_;

};

使用条件变量的示例:

/// 公共部分

// my_mutx m;

// my_condition c (m);

/// 消费者

m.acquire();

while (!condition_is_satisfied())

{

c.wait(300);

}

handle_something();

m.release();

/// 生产者

produce_something();

m.acquire();

c.signal();

m.release();

以上代码采用模板实现,变件变量类my_condition的模板参数是与条件变量配合使用的互斥量类型,为了方便直接使用,互斥量类型我也一并提供了: my_mutex。

代码我已在项目中测试使用过,如果发现问题,欢迎各路高手批评指正。

2018.6.11新增:

根据MSDN文档对SignalObjectAndWait函数的描述,本文描述的代码存在死锁的风险:条件满足的信号通知丢失。解决的方法就是在调用my_condition的wait方法时,一定要加上比较短的超时参数(比如300毫秒或者几秒,根据实际情况调整),循环检测以重新发现条件已经满足了(条件不会丢失,保存在信号量里)。MSDN原文如下:

Note that the "signal" and "wait" are not guaranteed to be performed as an atomic operation. Threads executing on other processors can observe the signaled state of the first object before the thread calling SignalObjectAndWait begins its wait on the second object.

---------------------

作者:leafarmy

来源:CSDN

原文:https://blog.csdn.net/leafarmy/article/details/4039548

版权声明:本文为博主原创文章,转载请附上博文链接!

java 条件变量_Windows下条件变量的实现相关推荐

  1. window安装python3装环境变量_Windows下的Python安装与环境变量的配置

    Windows下的Python安装与环境变量的配置 第一步:python下载: 第二步:python安装: 双击下载包,进入Python安装向导. 此处省略安装时的配图,下一步.下一步即可.但请要注意 ...

  2. windows中mysql添加环境变量_windows 下添加mysql到系统环境变量

    如何将MySQL添加到系统环境变量呢? 答: 在桌面选择"这台电脑"的图标,右键-->属性-->点击"高级系统设置"-->点击"环境 ...

  3. weka的java环境配置_windows下安装和配置Weka

    Weka是一款免费的,非商业化的,基于java环境下的开源的机器学习以及数据挖掘软件.Weka里含有各种数据挖掘工具:数据预处理,分类与回归,聚类,关联规则和可视化工具. 一.安装weka 我们首先需 ...

  4. cmd查看java环境变量_windows下 dos如何查看和设置环境变量?

    1.点击开始->运行->输入cmd 打开dos窗口 2.查看path变量值 C:\Users\ISSUSER.ISS201507151654>echo %path% E:\oracl ...

  5. mic系统装java开发软件_Windows下安装MicMac

    MicMac是一个免费开源的摄影测量套件,可用于各种3D场景重建,可以用于各个领域:制图,环境,工业,林业,遗产,考古学,...... 1 下载程序文件 2 安装 解压缩要安装的 "*.zi ...

  6. linux 添加了错误的PATH变量,linux下环境变量PATH设置错误的补救

    之前不小心在/etc/profile中添加了错误的PATH变量,导致几乎所有的系统命令无法使用,惊出一身冷汗,然后经过多次试验终于修复成功.以下是部分经验: 首先,PATH变量记录着各系统命令的存放路 ...

  7. Java线程:新特征-条件变量(转)

    条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往通过代码来赋予其含义. 这里的条件和 ...

  8. Java线程详解(16)-条件变量

    条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往通过代码来赋予其含义. 这里的条件和 ...

  9. java线程条件变量_使用条件变量(多线程笔记)

    条件变量属性: 使用条件变量可以以原子方式阻塞线程,知道某个特定条件为真为止.条件变量始终与互斥锁一起使用. 使用条件变量,线程可以以原子方式阻塞,知道满足某个条件为止.对掉件的测试时在互斥锁的保护下 ...

最新文章

  1. 2021牛客寒假算法基础集训营1 题解
  2. 订单倒计时取消,nodejs 辅助实现倒计时任务
  3. 今天且明白父母为什么生死度外的让孩子们读书
  4. c memcpy 与 strcpy 区别
  5. pytroch 数据增量 transforms的二十二个方法
  6. Centos7中Memcached安装使用说明
  7. 《Python Cookbook 3rd》笔记(1.7):字典排序
  8. .net生成缩略图,支持等比例缩放,加水印
  9. 30秒Python轻松入门-目录
  10. 深度学习入行门槛太低,不开心!
  11. wmsys.wm_concat的几个用法
  12. Kconfig Kbuild
  13. 自动阅读软件脚本应用开发app头条新闻引流阅读
  14. ai如何复制文字并对齐_AI文字怎么对齐? ai文字排版的方法
  15. Springboot 服务端为App集成支付宝支付
  16. c语言编程输出主析取范式,c++编程:从键盘上任意输入一个主析取范式,输出与之等值的主合取范式...
  17. MATLAB参数估计 置信区间
  18. c#中利用keybd_event函数+自定义软键盘实现中文输入时的问题
  19. 2021-05-26
  20. unity wsad 鼠标_Unity键盘WASD实现物体移动|chu

热门文章

  1. BFS+状态压缩 hdu-1885-Key Task
  2. [原创]RCP项目:数字图像处理软件
  3. C机顶盒开发实战常用初始化类型:数组、结构、指针
  4. Linux内核中流量控制(16)
  5. 如何使用idea远程debug调试代码详解
  6. 【工具收藏】golang 开发工具包,json、sql 转 struct
  7. python3 sorted排序代码示例
  8. 开启及关闭go mod
  9. 【网址收藏】windows安装Docker Desktop常见问题整理
  10. Python爬虫开发:requests库的使用--发送带参数post请求