C++核心准则CP.111:如果真的需要好双重检查锁,使用惯用模式
CP.111: Use a conventional pattern if you really need double-checked locking
CP.111:如果真的需要好双重检查锁,使用惯用模式
Reason(原因)
Double-checked locking is easy to mess up. If you really need to write your own double-checked locking, in spite of the rules CP.110: Do not write your own double-checked locking for initialization and CP.100: Don't use lock-free programming unless you absolutely have to, then do it in a conventional pattern.
双重检查锁容易把事情搞杂。如果你真的需要使用双重检查锁,而不管C++核心准则CP.100:不要使用无锁编程方式,除非绝对必要和C++核心准则CP.110:不要自已为初始化编写双重检查锁定代码中的建议,那么在使用双重检查锁时遵循惯用模式。
The uses of the double-checked locking pattern that are not in violation of CP.110: Do not write your own double-checked locking for initialization arise when a non-thread-safe action is both hard and rare, and there exists a fast thread-safe test that can be used to guarantee that the action is not needed, but cannot be used to guarantee the converse.
当非线程安全动作很难发生,而且存在快速的线程安全测试可以用于保证不需要该动作,但是无法保证相反的情况,可以使用没有违背C++核心准则CP.110:不要自已为初始化编写双重检查锁定代码准则的双重检查锁模式。
Example, bad(反面示例)
The use of volatile does not make the first check thread-safe, see also CP.200: Use volatile only to talk to non-C++ memory
volatile的使用没有让第一个检查线程安全,参见CP.200:只在谈到非C++内存的时候使用volatile
mutex action_mutex;
volatile bool action_needed;
if (action_needed) {
std::lock_guard<std::mutex> lock(action_mutex);
if (action_needed) {
take_action();
action_needed = false;
}
}
Example, good(范例)
mutex action_mutex;
atomic<bool> action_needed;
if (action_needed) {
std::lock_guard<std::mutex> lock(action_mutex);
if (action_needed) {
take_action();
action_needed = false;
}
}
Fine-tuned memory order may be beneficial where acquire load is more efficient than sequentially-consistent load
当顺序以执行负载比需求负载更高效时,调整良好的内存顺序可能更有利
mutex action_mutex;
atomic<bool> action_needed;
if (action_needed.load(memory_order_acquire)) {
lock_guard<std::mutex> lock(action_mutex);
if (action_needed.load(memory_order_relaxed)) {
take_action();
action_needed.store(false, memory_order_release);
}
}
Enforcement(实施建议)
??? Is it possible to detect the idiom?
有可能发现这种惯用法么?
原文链接https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp110-do-not-write-your-own-double-checked-locking-for-initialization
- 分布式消息队列 RocketMQ 源码分析 —— Message 拉取与消费(下)
- Spring Boot中使用RabbitMQ
- Spring Cloud构建微服务架构:消息驱动的微服务(入门)【Dalston版】
- 哪类人适合当产品经理?
- 产品经理·杂谈
- Python机器学习中的特征选择
- Android学习第八弹之改变状态栏的颜色使其与APP风格一体化
- 手把手教你 MongoDB 的安装与详细使用(二)
- 搭建 MongoDB分片(sharding) / 分区 / 集群环境
- Android调用手机中的应用市场,去评分的功能实现
- ANR 原理与实战技巧
- Android将应用程序的崩溃信息如何保存到本地文件,并上传至服务器
- android native内存检测方案(二)
- 测试数据集与验证数据集之间有什么区别呢?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面经手册 · 第3篇《HashMap核心知识,扰动函数、负载因子、扩容链表拆分深度学习(+实践验证)》
- Head First设计模式——桥接模式
- Head First设计模式——生成器模式和责任链模式
- Head First设计模式——蝇量模式和解释器模式
- 【每日一题】33. Search in Rotated Sorted Array
- 【每日一题】34. Find First and Last Position of Element in Sorted Array
- 【每日一题】35. Search Insert Position
- Head First设计模式——原型模式和访问者模式
- Java 新特性前瞻:封印类
- 每天手撕一道算法题-130. 被围绕的区域
- C#实现前向最大匹、字典树(分词、检索)
- Tomcat 中文乱码,设置UTF-8
- 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper
- IDEA将Maven项目中指定文件夹下的xml等文件编译进classes
- 数据误操作,教你使用ApexSQLLog工具从 SQLServer日志恢复数据!