atomic

原子操作CAS

狂风中的少年 提交于 2020-11-21 02:24:22
一、什么是原子操作 不可被中断的一个或者一系列操作、 CAS是Compare And Set的缩写,是以一种 无锁的方式实现并发控制 。在实际情况下,同时操作同一个对象的概率非常小,所以多数加锁操作做的是无用功, CAS以一种乐观锁的方式实现并发控制 。 二、实现原子操作的方式 Java可以通过锁和循环CAS的方式实现原子操作。 三、CAS( Compare And Swap ) 为什么要有CAS? Compare And Swap就是比较并且交换的一个原子操作,由Cpu在指令级别上进行保证。 为什么要有CAS:因为通过锁实现原子操作时,其他线程必须等待已经获得锁的线程运行完以后才能获得资源,这样就会占用系统的大量资源 四、 CAS包含哪些参数? CAS包含三个参数:1、变量所在内存地址V;2、变量对应的值A;3、我们将要修改的值B。如果说V上的变量的值是A的话,就用B重新赋值,如果不是A,那就什么事也不做,操作的返回结果原值是多少。 循环CAS:在一个(死)循环【for(;;)】里不断进行CAS操作,直到成功为止(自旋操作即死循环)。 五、CAS的原理 利用了现代处理器都支持的CAS的指令,循环这个指令,直到成功为止 六、CAS 实现原子操作的三大问题 1、 ABA问题:其他的线程把值改成了 B ,很快改成了A,原子操作的线程发现值是A就修改,这样会有问题。解决ABA,引入版本号

原子操作类 CAS

一个人想着一个人 提交于 2020-11-21 02:06:44
戳 蓝色字“ 码之初 ”关注,每天都进步! 来源: https://www.zhangjianbing.com/archives/54/ CAS (compare and swap),即:比较然后交换。 CAS 的原理 三个运算符:一个内存地址 V,一个期望值 A,一个新值 B。 基本思路:如果地址 V 上的值和期望值 A 相等,返回 true,并给地址 V 赋上新值 B,如果不是,返回 false,不做任何操作。 循环 (死循环,或者叫自旋) 里不断的进行 CAS 操作。 现代处理器都支持 CAS 的指令,循环这个指令,直到成功为止。 CAS 所带来的问题 1.ABA 问题。 所谓的 ABA 问题就是假设某个内存地址上有一个数值 A,但一个线程过来后把它变成了 B,然后又变回了 A,另一个线程过来后,发现内存地址上的值和期望的值一样,故 CAS 成功了,其实,内存地址上的值发生了变化,这种问题可以用加版本号的方式来解决。下面代码会演示。 2. 系统开销问题。 当一个 CAS 操作永远不成功,它就会一直自旋,系统开销巨大,遇到这种情况,我们只能使用 syn 锁或者其他锁的方式来替代 CAS 操作了。 3. 只能保证一个共享变量的原子操作。 就是只能够保证一个共享变量,如果想保证多个变量的话,可以将这些变量放入一个引用变量中,atomic 为我们提供了操纵引用变量的类,叫

OpenMP fortran 学习

女生的网名这么多〃 提交于 2020-11-20 08:01:32
参考自TAMU的PPThttps://people.math.umass.edu/~johnston/PHI_WG_2014/OpenMPSlides_tamu_sc.pdf 什么是OpenMP 在C、C++和FORTRAN中用于编写共享内存并行程序的事实上的标准API OpenMP API 由以下组成: 编译器指令 Compiler Directives 运行时 子程序/函数 Runtime subroutines/functions 环境变量 Environment variables 例子: 代码 PROGRAM HELLO !$OMP PARALLEL PRINT *,”Hello World” !$ OMP END PARALLEL STOP END 编译指令 intel: ifort -openmp -o hi.x hello.f pgi: pgfortran -mp -o hi.x hello.f gnu: gfortran -fopenmp -o hi.x hello.f 运行指令 Export OMP_NUM_THREADS=4 ./hi.x FORTRAN指令格式: !$ OMP PARALLEL [clauses] : !$OMP END PARALLEL OpenMP 遵循Fork/Join模型 OpenMP程序从一个线程开始;主线程(线程0)

OpenMP初探

纵饮孤独 提交于 2020-11-19 05:43:31
OpenMP支持c、cpp、fortran,本文对比使用openmp和未使用openmp的效率差距和外在表现,然后讲解基础知识。 一、举例 1、使用OpenMP与未使用OpenMP的比较。 OpenMP是使用多线程的接口。 以c语言程序举例,即ba.c文件如下: #include <omp.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> void Test( int n) { int j; for ( int i = 0 ; i < 100000000 ; ++ i) { // do nothing, just waste time j++ ; } printf( " %d, " , n); } int main( int argc, char * argv[]) { int i; #pragma omp parallel for for (i = 0 ; i < 100 ; ++ i) Test(i); system( " pause " ); return 1 ; } 在编译时,参数如下: 编译结果如下: 耗时:9s 注意 :我的电脑为双核,所以开启了4个线程分别运行 。 接下来,我通过window + R,输入msconfig,并进入boot中的高级设置,将我电脑的设置为单核,然后再运行同样的程序

微服务架构有毒,何时不使用微服务?

醉酒当歌 提交于 2020-11-18 17:48:50
在过去的四年中,使用微服务来构建应用程序似乎成了一种标准。大多数我所合作过的团队也对此表现出了不同程度的兴趣。 微服务所承诺的弹性、高可用、低耦合、敏捷,以及能够解决单体架构带来的问题,这些都是它流行的主要原因。 但是近段时间来,对于微服务的一些保留意见和注意事项似乎引起了人们的注意。 在这篇文章中,我重点想讨论的是微服务的应用,它的缺点是什么,以及在什么情况下应该慎重考虑使用微服务架构。 什么是微服务 在工业级别,关于微服务基本特征的定义比较一致。 这些特征可以总结如下: 微服务是一种应用于组件设计(服务如何分组)和部署架构(服务如何部署和通信)的模式。 微服务适用于创建具有“一定功能复杂性”的分布式应用程序。 各个服务必须小。 各个服务按功能划分,实现关注点分离。 各个服务保持自治和相互解耦,可以独立进行部署、版本控制和伸缩。 各个服务之间通过轻量级 API 和异步通道相结合的方式进行通信。 各个服务拥有独立的状态,并且只能通过服务本身来对其进行访问。 一个典型的微服务实现模式如下图: 图 1:典型的微服务实现模式 从上图中我们可以看到: 微服务中的每组服务有自己的前端 (由一个 API 和一个可选的 UI 组件组成)、一个实现自身服务领域逻辑的域层以及独立的数据存储。 前端复合。 将所有前端组件(UI 组件或 API)组合成一致前端(复合 UI 或 API 网关)。

Java并发编程:volatile关键字解析

那年仲夏 提交于 2020-11-13 13:00:11
volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。   volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。   以下是本文的目录大纲:   一.内存模型的相关概念   二.并发编程中的三个概念   三.Java内存模型   四..深入剖析volatile关键字   五.使用volatile关键字的场景   若有不正之处请多多谅解,并欢迎批评指正。   请尊重作者劳动成果,转载请标明原文链接:   http://www.cnblogs.com/dolphin0520/p/3920373.html 一.内存模型的相关概念   大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快

趣谈Linux操作系统学习笔记:第二十六讲

↘锁芯ラ 提交于 2020-11-13 06:51:33
一、内核页表 和用户态页表不同,在系统初始化的时候,我们就要创建内核页表了 我们从内核页表的根swapper_pg_dir开始找线索,在linux-5.1.3/arch/x86/include/asm/pgtable_64.h中就能找到它的定义 extern pud_t level3_kernel_pgt[512]; extern pud_t level3_ident_pgt[512]; extern pmd_t level2_kernel_pgt[512]; extern pmd_t level2_fixmap_pgt[512]; extern pmd_t level2_ident_pgt[512]; extern pte_t level1_fixmap_pgt[512]; extern pgd_t init_top_pgt[]; #define swapper_pg_dir init_top_pgt 1、swapper_pg_dir指向内核最顶级的目录pgd,同时出现的还有几个页表目录。我们可以回忆一下,64位系统的虚拟地址空间的布局 1、期中其中 XXX_ident_pgt 对应的是直接映射区 2、XXX_kernel_pgt 对应的是内核代码区 3、XXX_fixmap_pgt 对应的是固定映射区 2、它们是在哪里初始化的呢? 在汇编语言的文件里面的linux-5.1.3

java Atomic

你离开我真会死。 提交于 2020-11-08 16:30:32
一、何谓Atomic? Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位。计算机中的Atomic是指不能分割成若干部分的意思。如果一段代码被认为是Atomic,则表示这段代码在执行过程中,是不能被中断的。通常来说,原子指令由硬件提供,供软件来实现原子方法(某个线程进入该方法后,就不会被中断,直到其执行完成) 在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。 二、java.util.concurrent中的原子变量 无论是直接的还是间接的,几乎 java.util.concurrent 包中的所有类都使用原子变量,而不使用同步。类似 ConcurrentLinkedQueue 的类也使用原子变量直接实现无等待算法,而类似 ConcurrentHashMap 的类使用 ReentrantLock 在需要时进行锁定。然后, ReentrantLock 使用原子变量来维护等待锁定的线程队列。 如果没有 JDK 5.0 中的 JVM 改进