原子操作

C++11中的原子操作(atomic operation)

丶灬走出姿态 提交于 2019-12-15 20:07:08
C++11中的原子操作(atomic operation) 所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。也就是他确保了在同一时刻只有唯一的线程对这个资源进行访问。这有点类似互斥对象对共享资源的访问的保护,但是原子操作更加接近底层,因而效率更高。 在以往的C++标准中并没有对原子操作进行规定,我们往往是使用汇编语言,或者是借助第三方的线程库,例如intel的pthread来实现。在新标准C++11,引入了原子操作的概念,并通过这个新的头文件提供了多种原子操作数据类型,例如,atomic_bool,atomic_int等等,如果我们在多个线程中对这些类型的共享资源进行操作,编译器将保证这些操作都是原子性的,也就是说,确保任意时刻只有一个线程对这个资源进行访问,编译器将保证,多个线程访问这个共享资源的正确性。从而避免了锁的使用,提高了效率。 我们还是来看一个实际的例子。假若我们要设计一个广告点击统计程序,在服务器程序中,使用多个线程模拟多个用户对广告的点击: #include <boost/thread/thread.hpp> #include <atomic> #include <iostream> #include <time.h> using namespace

Redis 特点

余生长醉 提交于 2019-12-15 03:21:53
Redis 特点 Redis 与其他 key-value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。 Redis 优势 性能极高 – Redis读的速度是110000次/s,写的速度是81000次/s 。 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。 来源: CSDN 作者: _philosopher 链接: https://blog.csdn.net/qq_37003559/article/details/103493756

Redis学习之redis简介

不问归期 提交于 2019-12-14 00:51:35
目录 学习源 redis 简介 redis 优势 Redis与其他key-value存储有什么不同 key - value 存储 原子性操作 BSD协议 学习源 菜鸟教程 https://www.runoob.com/redis/redis-intro.html 简单教程 https://www.twle.cn/l/yufei/redis/redis-basic-intro.html redis 简介 Redis 是 完全开源免费的,遵守BSD协议,是一个高性能的NoSQL形式的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。 redis 优势 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子 – Redis的所有操作都是原子性的

Java并发之volatile关键字

筅森魡賤 提交于 2019-12-13 23:49:49
引言 说到多线程,我觉得我们最重要的是要理解一个临界区概念。 举个例子,一个班上1个女孩子(临界区),49个男孩子(线程),男孩子的目标就是这一个女孩子,就是会有竞争关系(线程安全问题)。推广到实际场景,例如对一个数相加或者相减等等情形,因为操作对象就只有一个,在多线程环境下,就会产生线程安全问题。理解临界区概念,我们对多线程问题可以有一个好意识。 Jav内存模型(JMM) 谈到多线程就应该了解一下Java内存模型(JMM)的抽象示意图.下图: 线程A和线程B执行的是时候,会去读取共享变量(临界区),然后各自拷贝一份回到自己的本地内存,执行后续操作。 JMM模型是一种规范,就像Java的接口一样。JMM会涉及到三个问题:原子性,可见性,有序性。 所谓原子性。就是说一个线程的执行会不会被其他线程影响的。他是不可中断的。举个例子: int i=1 这个语句在Jmm中就是原子性的。无论是一个线程执行还是多个线程执行这个语句,读出来的i就是等于1。那什么是非原子性呢,按道理如果Java的代码都是原子性,应该就不会有线程问题了啊。其实JMM这是规定某些语句是原子性罢了。举个非原子性例子: i ++; 这个操作就不是原子性的了。因为他就是包含了三个操作:第一读取i的值,第二将i加上1,第三将结果赋值回来给i,更新i的值。 所谓可见性。可见性表示如果一个值在线程A修改了

Java多线程进阶—— J.U.C之atomic框架:Atomic数组

十年热恋 提交于 2019-12-13 00:47:51
一、Atomic数组简介 Atomic数组,顾名思义,就是能 以原子的方式,操作数组中的元素 。 JDK提供了三种类型的原子数组: AtomicIntegerArray 、 AtomicLongArray 、 AtomicReferenceArray 。 这三种类型大同小异,AtomicIntegerArray对应AtomicInteger,AtomicLongArray对应AtomicLong,AtomicReferenceArray对应AtomicReference。 其实阅读源码也可以发现,这些数组原子类与对应的普通原子类相比,只是 多了通过索引找到内存中元素地址的操作 而已。 注意:原子数组并不是说可以让线程以原子方式一次性地操作数组中所有元素的数组。 而是指对于数组中的每个元素,可以以原子方式进行操作。 说得简单点, 原子数组类型 其实可以看成 原子类型组成的数组 。 比如: AtomicIntegerArray array = new AtomicIntegerArray(10); array.getAndIncrement(0); // 将第0个元素原子地增加1 等同于 AtomicInteger[] array = new AtomicInteger[10]; array[0].getAndIncrement(); // 将第0个元素原子地增加1 二

CAS都不了解,你还怎么看J.U.C

◇◆丶佛笑我妖孽 提交于 2019-12-11 20:07:56
  说到CAS(CompareAndSwap),不得不先说一说悲观锁和乐观锁,因为CAS是乐观锁思想的一种实现。      悲观锁:总是很悲观的认为,每次拿数据都会有其他线程并发执行,所以每次都会进行加锁,用完之后释放锁,其他的线程才能拿到锁,进而拿到资源进行操作。java中的synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。      乐观锁:总是很乐观认为,自己拿到数据操作的时候,没有其他线程来并发操作,等自己操作结束要更新数据时,判断自己对数据操作的期间有没有其他线程进行操作,如果有,则进行重试,直到操作变更成功。乐观锁常使用CAS和版本号机制来实现。java中java.util.atomic包下的原子类都是基于CAS实现的。      一、什么是CAS      CAS指CompareAndSwap,顾名思义,先比较后交换。比较什么?交换什么呢?      CAS中有三个变量:内存地址V,期待值A, 更新值B。      当且仅当内存地址V对应的值与期待值A时相等时,将内存地址V对应的值更换为B。      二、atomic包      有了悲观锁,乐观锁的知识,让我们走进java.util.atomic包,看一看java中CAS的实现。      这就是java.util.atomic包下的类,我们着重看AtomicInteger源码

CAS都不了解,你还怎么看J.U.C

百般思念 提交于 2019-12-11 17:46:10
前言 说到 CAS (CompareAndSwap),不得不先说一说 悲观锁 和 乐观锁 ,因为CAS是乐观锁思想的一种实现。 悲观锁 :总是很悲观的认为,每次拿数据都会有其他线程并发执行,所以每次都会进行加锁,用完之后释放锁,其他的线程才能拿到锁,进而拿到资源进行操作。java中的synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁 :总是很乐观认为,自己拿到数据操作的时候,没有其他线程来并发操作,等自己操作结束要更新数据时,判断自己对数据操作的期间有没有其他线程进行操作,如果有,则进行重试,直到操作变更成功。乐观锁常使用CAS和版本号机制来实现。java中 java.util.atomic 包下的原子类都是基于CAS实现的。 一、什么是CAS CAS指 CompareAndSwap ,顾名思义, 先比较后交换 。比较什么?交换什么呢? CAS中有三个变量:内存地址V,期待值A, 更新值B。 当且仅当内存地址V对应的值与期待值A时相等时,将内存地址V对应的值更换为B。 二、atomic包 有了悲观锁,乐观锁的知识,让我们走进java.util.atomic包,看一看java中CAS的实现。 这就是 java.util.atomic 包下的类,我们着重看AtomicInteger源码(其他的都是一样的思想实现的) 然后思考CAS有什么弊端

Java并发编程系列-(3) 原子操作与CAS

余生颓废 提交于 2019-12-10 23:39:26
3. 原子操作与CAS 3.1 原子操作 所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何context switch,也就是切换到另一个线程。 为了实现原子操作,Java中可以通过synchronized关键字将函数或者代码块包围,以实现操作的原子性。但是synchronized关键字有一些很显著的问题: 1、synchronized是基于阻塞锁的机制,如果被阻塞的线程优先级很高,可能很长时间其他线程都没有机会运行; 2、拿到锁的线程一直不释放锁,可能导致其他线程一直等待; 3、线程数量很多时,可能带来大量的竞争,消耗cpu,同时带来死锁或者其他安全。 像synchronized这种独占锁属于悲观锁,它是在假设一定会发生冲突的,那么加锁恰好有用,除此之外,还有乐观锁,乐观锁的含义就是假设没有发生冲突,那么我正好可以进行某项操作,如果要是发生冲突呢,那我就重试直到成功,乐观锁最常见的就是CAS。 JAVA内部在实现原子操作的类时都应用到了CAS。 3.2 CAS CAS是CompareAndSwap的缩写,即比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。 CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作

线程安全

╄→гoц情女王★ 提交于 2019-12-10 14:22:13
在这三篇文章中,我将详细介绍原理操作,内存障碍和线程之间数据的快速交换,以及“sequence-points”示例中的“execute-around-idiom”。同时,我们将尝试一起做一些有用的事情。 标准C ++库中没有线程安全的容器(数组,列表,映射…),可以在多个线程中使用它们而无需附加锁。在使用标准容器进行多线程交换的情况下,可能会忘记使用互斥锁保护其中一个代码段,或者错误地使用另一个互斥锁来保护它。 显然,如果开发人员使用自己的解决方案而不是标准的解决方案,则会犯更多的错误。而且,如果任务很复杂,以至于没有任何标准解决方案,那么开发人员在尝试寻找解决方案时将充满错误。 依靠“实践大于理论”的原则,我们将努力创造出一个解决这个问题的最佳方法,而不是纸上谈兵。 在本文中,我们将实现使所有对象成为线程安全对象的智能指针,其性能与优化的无锁容器相同。 使用此类指针的简化,非优化示例: int main() {   contfree_safe_ptr< std::map< std::string, int > > safe_map_string_int;   std::thread t1( & { safe_map_string_int->emplace(“apple”, 1); });   std::thread t2( & { safe_map_string_int-

R语言

风流意气都作罢 提交于 2019-12-06 23:24:26
1、R语言介绍 R和RStudio 是与计算机进行对话的两个工具 RStudio 是话筒 R是沟通所用的语言 R的由来:基于S语言,由新西兰奥克兰大学的Robert Gentleman和Ross Ihaka开发,因两位开发者名字首字母都是R,所以该语言命名为R。 怎样理解R 一种计算机语言 一种用于统计分析、绘图的操作环境 用户接口 R 语言特点 R 是一款开源、免费的软件,可以跨平台运行 R 提供了非常丰富的统计分析技术 有很多非常实用并包含最新技术的R包,而且更新速度非常快 R的绘图功能十分强大 软件界面: 配置文件,选择SDI单窗口 选择save进行直接保存修改,不需要更改路径 效果图: R环境下的提示符: 2、R包的安装 下载包: 查看所有包的命名: (.packages(all=T)) 加载包命令: 没有任何提示表示结果正常 向量的长度=向量的个数 字符串向量,双引号 “ ” c函数:拼接功能 同时下载两个包 install.packages(c("reshape2","dplyr")) 创建R对象 R语言区分大小写 对象sz <-赋值符号 1:6数值 sz<-1:6 连续赋值: ls()函数调取所有对象 get()函数得到变量的数值 删除对象: 删除所有对象 rm(list=ls()) 统计函数 sum() sz+1:2 sz+1:4 元素方式运算