const 和 mutable在C++存在已经很多年了,对于如今的这两个关键字你了解多少?

Problem

JG Question

1. 什么是“共享变量”?

Guru Question

2. const 和 mutable对于共享变量来说意味着什么?

3. 在C++98和C++11两者间,const 和 mutable有什么区别?

Stop and thinking……

Solution

1. 什么是“共享变量”?

共享变量是在同一时间可以被多个线程同时访问的变量。

这个概念在C++内存模型中很重要。例如:C++内存模型禁止创造一个写入“潜在共享变量区”,这不会被写入到程序执行的顺序一致(sequentially consistent)。当C++标准库禁止通过(其他)线程访问修改对象指的就是这节。

2. const 和 mutable对于共享变量来说意味着什么?
     从C++11开始,变量加上const可能共享对于并发来说,意思是“只读或几乎和只读一样”。在同一对象上的并发const操作要求在没有调用代码做外部同步是安全的。如果你在实现一个类型,除非你知道这个类型的对象绝不会被共享(通常不可能),这几意味着你的每一个const成员函数必须满足其下一点:

· 这个对象真正的是物理上/按位的const,意味着在对象的数据上不执行写动作;
   · 内部同步,这样如果在对象的数据上做了写的动作,那么数据可以通过mutex或者同等性质的(或者是atomic<>)来保证数据的正确性,因此任何可能多调用的并发const访问都不能辨别其中的差别。(相同的)

类型没有遵循以上任意其中一点,那么都不能和标准库一起使用。详细参照ISO C++ §17.6.5.9

同样地,在mutable的成员变量上写总意味着:此变量是“可写的但逻辑上是const的”。这意味着:

·“逻辑上const”部分的意思是“可以被多个并发const操作安全地使用”;
       ·”mutable“和”可写性“部分的意思是一些const操作可能确实会对共享变量进行写的动作,这意味着在对变量进行读和写是内在正确的,因此它应该使用mutex或相同的东西来保护,或者使用atomic<>。

通常情况下:

Guideline:记住”M&M规则“:对于成员变量来说,mutable和mutex(或atomic)是一起使用的。

这是双向的,也就是:
     ·(1)对于成员变量,mutable意味着mutex(或等价物):一个mutable的成员变量假定是一个可变的共享变量,因此必须是内在同步的,使用mutex,称atomic或者同类的东西来保护。
     ·(2)对于成员变量,mutex(或同等的同步类型)意味着mutable:一个成员变量它本身是同步类型,比如mutex或条件变量(condition variable),自然地需要mutable,因为你可能会在并发的const成员函数中以非const的方式来使用它(比如:使用std::lock_guard<mutex>)

我们或在GotW #6b的第二部分看到例子。

3. 在C++98和C++11两者间,const 和 mutable有什么区别?

首先澄清一点:C++98单线程代码依旧是能正常运行的。C++11对C++98有相当好的兼容,即使是在const的语义上有着进化。C++98单线程代码使用老的”逻辑const“意味着const依然是有效的。

随着C++98,我们告诫一整代C++开发者,”const意味的是逻辑上的const,不是物理上/按位的const“。这也就是,在C++98中,我们教授的是const只意味着对象的可观察状态(就是说,通过非private成员函数)不应该改变直到调用者调用。但是它的内部位可能是改变了的,为了更新计数器和一些设施,其他数据通过类型的public或protected接口是不能访问的。

这些定义对于并发来说是不够的。在C++11和之后的版本中,标准库中包含了并发的内存模型和线程安全规范。这也使得更简单一些:现在const真的是意味着”只读“或安全的并发读取,要不真正在物理上/按位const,或者内部同步。因此对于任意可能的并发const访问的写都是同步的,这样调用者就不会知道其中存在不同。

尽管已存在的C++98年代的类型在C++98年代的单线程中依旧能运行正常,这些类型和一些你现在所编写的类型都应该遵循新的更严格的要求,如果它们可能用在多线程中。好消息是那么已经存在的类型已经遵循了这个规则。在单线程中依赖于强制去掉const和/或使用mutable的数据成员已经被普遍质疑和罕见。

原文地址:http://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/

[译]GotW #6a: Const-Correctness, Part 1的更多相关文章

  1. [译]GotW #6b Const-Correctness, Part 2

         const和mutable对于书写安全代码来说是个很有利的工具,坚持使用它们. Problem Guru Question 在下面代码中,在只要合适的情况下,对const进行增加和删除(包括 ...

  2. [译]GotW #4 Class Mechanics

    你对写一个类的细节有多在行?这条款不仅注重公然的错误,更多的是一种专业的风格.了解这些原则将会帮助你设计易于使用和易于管理的类. JG Question 1. 什么使得接口“容易正确使用,错误使用却很 ...

  3. [译]GotW #3: Using the Standard Library (or, Temporaries Revisited)

    高效的代码重用是良好的软件工程中重要的一部分.为了演示如何更好地通过使用标准库算法而不是手工编写,我们再次考虑先前的问题.演示通过简单利用标准库中已有的算法来避免的一些问题. Problem JG Q ...

  4. [译]GotW #2: Temporary Objects

        不必要的和(或)临时的变量经常是罪魁祸首,它让你在程序性能方面的努力功亏一篑.如何才能识别出它们然后避免它们呢? Problem JG Question: 1. 什么是临时变量? Guru Q ...

  5. [译]GotW #89 Smart Pointers

    There's a lot to love about standard smart pointers in general, and unique_ptr in particular. Proble ...

  6. [译]GotW #1: Variable Initialization 续

    Answer 2. 下面每行代码都做了什么? 在Q2中,我们创建了一个vector<int>且传了参数10和20到构造函数中,第一种情况下(10,20),第二种情况是{10, 20}. 它 ...

  7. [译]GotW #1: Variable Initialization

    原文地址:http://herbsutter.com/2013/05/09/gotw-1-solution/ 第一个问题强调的是要明白自己在写什么的重要性.下面有几行简单的代码--它们大多数之间都有区 ...

  8. [译]GotW #5:Overriding Virtual Functions

       虚函数是一个很基本的特性,但是它们偶尔会隐藏在很微妙的地方,然后等着你.如果你能回答下面的问题,那么你已经完全了解了它,你不太能浪费太多时间去调试类似下面的问题. Problem JG Ques ...

  9. Meaning of “const” last in a C++ method declaration?

    函数尾部的const是什么意思? 1 Answer by Jnick Bernnet A "const function", denoted with the keyword co ...

随机推荐

  1. ajax跨域请求的解决方案

    一直打算改造一下自己传统做网站的形式. 我是.Net程序员,含辛茹苦数年也没混出个什么名堂. 最近微信比较火, 由于现在大环境的影响和以前工作的总结和经验,我打算自己写一个数据,UI松耦合的比较新潮的 ...

  2. php嵌入html的解析过程

    php嵌入html的解析过程 示例: 执行过程:     首先明确:PHP是分段读取一次执行(编译),JS是分段读取分段执行   程序就是对内存的操作     函数可以先调用后定义,原因,程序的执行时 ...

  3. OpenJudge/Poj 1004 Financial Management

    1.链接地址: http://poj.org/problem?id=1004 http://bailian.openjudge.cn/practice/1004 2.题目: 总时间限制: 1000ms ...

  4. DataTable 数据量大时,导致内存溢出的解决方案

    /// <summary> /// 分解数据表 /// </summary> /// <param name="originalTab">需要分 ...

  5. 网页frame引入实现全屏滚动,使用jquery实现浏览器兼容

    近期做一个项目,其中有一个需求,就是网页中需要用frame引入页面并实现frame的全屏,在网上查了好多感觉方式都不尽相同,但是都不是介绍的很全面,浏览器的兼容也做的不好,自己总结了一些要点,需要的可 ...

  6. windows 7 64bit 下apache php mysql 环境配置

    在64位环境下安装apache,php和配置过程 准备好安装包.(64位版本) Apache 下载地址:http://www.apachelounge.com/download/ Php 下载地址:h ...

  7. JAVA学习资料整理

    今天偶然间发现之前一个群里发过的一篇关于JAVA学习资料的东西.本着服务大众的精神,搬来了博客园: <JAVA编程思想>第四版(英文原版) 下载地址:http://115.com/file ...

  8. Oracle wrap 测试的一些细节问题

    今天在做 wrap 的测试实验的时候,出现一个很奇怪的现象,就是加密不成功.具体表现为:1.加密后的文件大小为0kb. 2.加密后的文件仍然可视. 具体测试步骤如下: D:\Just4work\som ...

  9. Authentication for the REST APIs

    HTTP基本认证原理 在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份认证的方法,当一个客户端向HTTP服务器进行数据请求时,如果客户端未被 ...

  10. Word分栏

    情景描述 Word分栏在小论文的撰写过程中是很常用的技术.但是,我们经常会遇到很难过的情况: 一段文字本来是连续分布的,可是当选择了分两栏         之后,开始部分在左边一栏,中间在右边一栏. ...