通过atomic_flag简单自旋锁实现简单说明标准库中锁使用的memory_order
在使用标准库中的加锁机制时,例如我们使用std::mutex,写了如下的代码(下面的代码使用condition_variable可能更合适)
std::mutex g_mtx;
int g_resNum;
// and how to get the resource
... // 线程1使用如下代码:
{
std::lock_guard<std::mutex> guard(g_mtx);
// prepare the resource
...
// set the resource num
g_resNum = ...;
} // 线程2使用如下的代码:
{
std::lock_guard<std::mutex> guard(g_mtx);
// check the g_resNum
if (g_resNum > )
{
...
}
}
我们知道如果先运行线程1的代码,也就是说线程1获得了锁,进行了准备资源的操作。然后运行线程2,也就是说线程2之后获得了锁,可以知道线程1加锁区域的代码已经执行完毕,而且对线程2可见,我们可以放心的使用线程1中设置的资源。这里面的原因是
标准库在实现std::mutex过程中使用了memory_order。http://en.cppreference.com/w/cpp/atomic/memory_order 中的描述如下:
Acquire operation
Atomic load with memory_order_acquire or stronger is an acquire operation. The lock() operation on a Mutex is also an acquire operation.
Release operation
Atomic store with memory_order_release or stronger is a release operation. The unlock() operation on a Mutex is also a release operation.
C++ atomic中对Acquire- Release ordering的简单介绍如下:
If an atomic store in thread A is tagged memory_order_release and an atomic load in thread B from the same variable is tagged memory_order_acquire, all memory writes (non-atomic and relaxed atomic) that happened-before the atomic store from the point of view of thread A, become visible side-effects in thread B, that is, once the atomic load is completed, thread B is guaranteed to see everything thread A wrote to memory.
关于memory_order的简单介绍就到这里,下面我用一个很简单的spinlock的实现来简单说明一下memory_order的使用:
class spinlock_mutex
{
std::atomic_flag flag;
public:
spinlock_mutex() :
flag(ATOMIC_FLAG_INIT)
{} void lock()
{
while(flag.test_and_set(std::memory_order_acquire));
} bool try_lock()
{
if (flag.test_and_set(std::memory_order_acquire))
return false; return true;
} void unlock()
{
flag.clear(std::memory_order_release);
}
};
上述spinlock实现存在性能上的问题,网上有关于这个实现问题的讨论,参考网址:https://www.zhihu.com/question/55764216
希望能给初学C++标准库多线程的程序员有所启示。
通过atomic_flag简单自旋锁实现简单说明标准库中锁使用的memory_order的更多相关文章
- 在C++11编译环境中,简单自测了一下C++标准库中的string/vector和迭代器,记录一下
#include <iostream> #include <vector> using namespace std; int main() { //////////////// ...
- 如何美观地打印 Python 对象?这个标准库可以简单实现
前不久,我写了一篇文章回顾 Python 中 print 的发展历史 ,提到了两条发展线索: 明线:早期的 print 语句带有 C 和 Shell 的影子,是个应用程序级的 statement,在最 ...
- SQL Server中的锁的简单学习
简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的 ...
- Innodb 锁 (简单笔记)
看过很多innodb锁的文章,已经明白的就不写了,简单做个笔记 Innodb 锁的兼容性: 1.意向锁和意向锁之间都是兼容的 2.X(排他锁)与任何锁都是不兼容的 3.排他意向锁 IX 于S锁是不 ...
- Redisson分布式锁的简单使用
一:前言 我在实际环境中遇到了这样一种问题,分布式生成id的问题!因为业务逻辑的问题,我有个生成id的方法,是根据业务标识+id当做唯一的值! 而uuid是递增生成的,从1开始一直递增,那么在同一台机 ...
- Mysql锁机制简单了解一下
历史文章推荐: 可能是最漂亮的Spring事务管理详解 面试中关于Java虚拟机(jvm)的问题看这篇就够了 Java NIO 概览 关于分布式计算的一些概念 一 锁分类(按照锁的粒度分类) Mysq ...
- Redis分布式锁实现简单秒杀功能
这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...
- Java内置锁和简单用法
一.简单的锁知识 关于内置锁 Java具有通过synchronized关键字实现的内置锁,内置锁获得锁和释放锁是隐式的,进入synchronized修饰的代码就获得锁,走出相应的代码就释放锁. jav ...
- 单实例redis分布式锁的简单实现
redis分布式锁的基本功能包括, 同一刻只能有一个人占有锁, 当锁被其他人占用时, 获取者可以等待他人释放锁, 此外锁本身必须能超时自动释放. 直接上java代码, 如下: package com. ...
随机推荐
- [Codeforces Round #526 (Div. 2)]
https://codeforces.com/contest/1084 A题 数据量很小,枚举就行 #include<iostream> #include<cstdio> #i ...
- debian 安装使用NTP
编程之路刚刚开始,错误难免,希望大家能够指出. 领导要求,要4台机器时钟同步,上网查了查,主要看了看ptp和ntp,感觉ntp就够用,索性就直接上手ntp了. 以下内容纯属最基础的内容,只适合第一次接 ...
- 【java多线程】java8的流操作api和fork/join框架
原文:https://blog.csdn.net/u011001723/article/details/52794455/ 一.测试一个案例,说明java8的流操作是并行操作 1.代码 package ...
- Create-React-App脚手架使用方法
Facebook 官方推出Create-React-App脚手架,基本可以零配置搭建基于webpack的React开发环境,内置了热更新等功能. 由于create-react-app命令预先安装和配置 ...
- JQuery中serialize()方法的使用
- centos 7.0 lnmp成功安装过程(很乱)
下载nginx [root@localhost src]# wget http://nginx.org/download/nginx-1.7.9.tar.gz --2015-01-24 12:55:2 ...
- 有用的proc文件系统文件
1. /proc/iomem I/O内存映射 2. /proc/meminfo 系统内存信息
- Tower Defense Toolkit 学习
代码太多,就不贴了.用到的基本已注释. 游戏中的数据存放在Resources/Database中.游戏运行时,通过Resources.Load加载 UI构成 对象池 using UnityEngi ...
- TypeScript 之 声明文件的结构
https://www.tslang.cn/docs/handbook/declaration-files/library-structures.html 模块化库 一些库只能工作在模块加载器的环境下 ...
- jQuery的ready()事件与js中的onload事件的区别
出处:http://blog.csdn.net/yuanmei1986/article/details/50781453