简介
在多进程(线程)访问资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源。
原子操作:UP和SMP的异同
-----------------------------------------------------------
"原子操作(atomic operation)是不需要synchronized",这是Java多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。 通常所说的原子操作包括对非long和double型的primitive进行赋值,以及返回这两者之外的primitive。之所以要把它们排除在外是因为它们都比较大,而JVM的设计规范又没有要求读操作和赋值操作必须是原子操作(JVM可以试着去这么作,但并不保证)。不过如果你在long或double前面加了volatile,那么它就肯定是原子操作了。
特性
原子操作是不可分割的,在执行完毕不会被任何其它任务或事件中断。在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。这也是某些CPU指令系统中引入了test_and_set、test_and_clear等指令用于临界资源互斥的原因。但是,在对称多处理器(Symmetric Multi-Processor)结构中就不同了,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。我们以decl (递减指令)为例,这是一个典型的"读-改-写"过程,涉及两次内存访问。设想在不同CPU运行的两个进程都在递减某个计数值,可能发生的情况是:
1. CPU A(CPU A上所运行的进程,以下同)从内存单元把当前计数值(2)装载进它的寄存器中;
2. CPU B从内存单元把当前计数值(2)装载进它的寄存器中。
3. CPU A在它的寄存器中将计数值递减为1;
4. CPU B在它的寄存器中将计数值递减为1;
5. CPU A把修改后的计数值(1)写回内存单元。
6. CPU B把修改后的计数值(1)写回内存单元。
我们看到,内存里的计数值应该是0,然而它却是1。如果该计数值是一个共享资源的引用计数,每个进程都在递减后把该值与0进行比较,从而确定是否需要释放该共享资源。这时,两个进程都去掉了对该共享资源的引用,但没有一个进程能够释放它--两个进程都推断出:计数值是1,共享资源仍然在被使用。
硬件支持
原子性不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。
分享到:
相关推荐
分布式Redis原子操作示例,近期项目中遇到分布式项目中多节点大并发操作redis同一个key。此案例利用java调用LUA脚本实现redis操作的原子性。分享出来大家参考。
串口方式:用串口接收中断方式接收,不是DMA. 遇到的问题:串口数据有帧丢失。 原因描述:在串口接收中断中接收到字节时变量size...实际的原因是对size的操作不是原子操作的,具体更改见文档。有相关程序和具体的分析。
在kotlin中使用原子操作的惯用方法。
多线程程序中的原子操作
C++多线程原子操作实现方法。很很详解!
原子操作、信号量、读写信号量和自旋锁的API.希望能帮助大家
测试了windows下原子操作api的使用,很简单的测试,还是比较有趣的
1.认识原子操作 原子操作就是在多线程程序中“最小的且不可并行化的”操作,意味着多个线程访问同一个资源时,有且仅有一个线程能对资源进行操作。通常情况下原子操作可以通过互斥的访问方式来保证,例如Linux下的...
NULL 博文链接:https://peter8015.iteye.com/blog/975250
同步之原子操作.pptx
各位只需要将CLib4Swift.h、CLib4Swift.c以及SwiftAtomic.swift三个文件放入到自己项目工程中即可,然后还需要将"CLib4Swift.h"头文件include到你的brdige头文件中。 具体使用非常简单,直接看main.swift中的测试...
atomic_ops原子操作1
原子操作 四种原子更新方式文档,分别是原子更新基本类型,原子更 新数组,原子更新引用和原子更新字段。Atomic包里的类基本都是使用Unsafe实现的包装 类
MongoDB原子操作.pdf 学习资料 复习资料 教学资源
linux下原子操作程序源码
原子操作类, 发容器 & 并发工具, 线程池, 并发实践 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行。Java具有简单、可移植、高性能和...
MongoDB原子操作与GridFS.pdf 学习资料 复习资料 教学资源
如两个线程操作同一变量过程中,一个线程执行过程中可能被内核临时挂起,这就是线程切换,当内核再次切换到该线程时,之前的数据可能已被修改,不能保证原子操作。 C++11提供了个原子的类和方法atomic,保证了多线程...
Linux驱动并发控制之位原子操作.pdf