谈谈C++的volatile关键字以及常见的误解
作者:。)
按照C++标准,这是volatile唯一的功能,但是在一些编译器(如,MSVC)中,volatile还有线程同步的功能,但这就是编译器自己的拓展了,并不能跨平台应用。
对volatile常见的误解
实际上“volatile可以在线程间同步”也是比较常见的误解。比如以下的例子:
class AObject { public: void wait() { m_flag = false; while (!m_flag) { this_thread::sleep(1000ms); } } void notify() { m_flag = true; } private: volatile bool m_flag; }; AObject obj; ... // Thread 1 ... obj.wait(); ... // Thread 2 ... obj.notify(); ...
对volatile有误解的人,或者对并发编程不了解的人可能会觉得这段逻辑没什么问题,可能会认为volatile保证了,wait()对m_flag的读取,notify()对m_flag的写入,所以Thread 1能够正常醒来。实际上并不是,Thread 1可能永远看不到m_flag变成true。因为在多核CPU中,每个CPU都有自己的缓存。缓存中存有一部分内存中的数据,CPU要对内存读取与存储的时候都会先去操作缓存,而不会直接对内存进行操作。所以多个CPU“看到”的内存中的数据是不一样的,这个叫做内存可见性问题(memory visibility)。并发编程下,一个程序可以有多个线程在不同的CPU核中同时运行,这个时候内存可见性就会影响程序的正确性。放到例子中就是,Thread 2修改了m_flag对应的内存,但是Thread 1在其他CPU核上运行,而两个CPU缓存和内存没有做同步,导致Thread 1运行的核上看到的一直都是旧的数据,于是Thread 1永远都不能醒来。内存可见性问题不是多线程环境下会遇到的唯一的问题,CPU的乱序执行也会导致一些意想不到的事情发生,关于这点volatile能做的也是有限的。这些都是属于并发编程的内容,在此我就不多做展开,总之volatile关键字对并发编程基本是没有帮助的。
那么用不了volatile,我们该怎么修改上面的例子?C++11开始有一个很好用的库,那就是atomic类模板,在<atomic>头文件中,多个线程对atomic对象进行访问是安全的。以下为修改后的代码:
class AObject { public: void wait() { m_flag = false; while (!m_flag) { this_thread::sleep(1000ms); } } void notify() { m_flag = true; } private: atomic<bool> m_flag; };
只要把“volatile bool”替换为“atomic<bool>”就可以。<atomic>头文件也定义了若干常用的别名,例如“atomic<bool>”就可以替换为“atomic_bool”。atomic模板重载了常用的运算符,所以atomic<bool>使用起来和普通的bool变量差别不大。一些atomic的高级用法,由于要涉及到C++的内存模型与并发编程,我就不在此展开了,以后有时间再补上。
相关文章:
-
-
【淘宝客】根据淘客联盟精选清单(淘宝天猫内部优惠券)搜索淘宝天猫优惠券dome-分页版
这篇文章,可能是淘宝天猫内部优惠券最后一篇了,中间也遇到许多问题,毕竟自己也就会写一点点前端,所以给这篇文章先来个总结: 1、excel转dat文件... [阅读全文] -
RabbitMQ在PHP使用,我在这里对RabbitMQ的各项方法和参数进行了一些梳理,有不足的地方还望各位大神指点.想要使用rabbitMQ消息队... [阅读全文]
-
”工欲善其事,必先利其器“,古人说的很对,虽然不能做一个单纯的”工具帝“,但是自己有合适的工具集真的很关键。以前认识一个做逆向工程的高手,有自己的”... [阅读全文]
-
我在之前的随笔中介绍了function如何保存参数,如何实现调用相关知识。对于一个函数对象或者函数指针来说,应该很容易理解。不过对于如何在funct... [阅读全文]
-
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的“可能比较准确”的「翻译」。 Chapter 2 构造 / 析构 /... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
上一篇: 一个SQL查询导出数据字典
发表评论