`

原子操作

    博客分类:
  • JESE
阅读更多

简介

在多进程(线程)访问资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源。

  原子操作: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就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

分享到:
评论

相关推荐

    STM32的串口变量的原子操作问题

    ### STM32串口变量的原子操作问题详解 #### 一、问题背景及描述 在进行STM32单片机的串口通信开发过程中,可能会遇到串口数据帧丢失的问题。这种现象通常表现为:尽管串口接收到了完整的数据包(如512个字节或1024...

    多线程程序中的原子操作

    ### 多线程程序中的原子操作 #### 一、引言 在多线程编程中,原子操作是一个至关重要的概念。原子操作指的是不可再分割的操作,即在一个操作执行的过程中不会被其他线程打断。这对于保证多线程程序的正确性和避免...

    分布式Redis原子操作示例

    分布式Redis原子操作示例,近期项目中遇到分布式项目中多节点大并发操作redis同一个key。此案例利用java调用LUA脚本实现redis操作的原子性。分享出来大家参考。

    kotlinx.atomicfu,在kotlin中使用原子操作的惯用方法.zip

    Kotlinx.AtomicFu是Kotlin社区的一个开源项目,它提供了在Kotlin中使用原子操作(Atomic Operations)的简便工具和库。这个项目主要是为了解决多线程环境下的并发问题,尤其是在非Java平台如JavaScript或者Native上...

    C++多线程原子操作

    在C++编程中,多线程环境下的原子操作(Atomic Operations)是确保程序并发执行时数据一致性的重要机制。原子操作是指不可分割的操作,一旦开始执行,就不会被其他线程中断,直到该操作完成。在多线程环境中,不使用...

    windows c++ 原子操作例子

    在Windows平台上,C++编程中使用原子操作(Atomic Operations)是为了保证多线程环境下的数据一致性,避免竞态条件和死锁等问题。原子操作是指在多线程环境下,该操作会被完整无中断地执行,不会被其他线程打断。...

    原子操作、信号量、读写信号量和自旋锁的API

    ### 原子操作、信号量、读写信号量和自旋锁的API详解 #### 一、引言 在现代操作系统中,特别是在多处理器环境下,确保数据的一致性和完整性至关重要。为此,Linux内核提供了多种同步机制来保护共享资源免受并发...

    java多线程中的原子操作

    在Java多线程编程中,原子操作是一种非常关键的概念,它涉及到并发控制和线程安全。原子操作是指在不被其他线程中断的情况下,能够完整执行的一个或一系列操作。这样的操作在多线程环境中可以保证数据的一致性和完整...

    并发编程——原子操作CAS.pdf

    本文档详细介绍了并发编程中的原子操作,特别是Java语言中通过CAS(Compare-And-Swap)实现的原子操作,并指出了在实际编程中如何使用和实现原子操作。 首先,文档开篇就介绍了原子操作的定义。所谓原子操作,指的...

    同步之原子操作.pptx

    ARM 原子操作与同步机制 ARM 架构中的原子操作是指在多处理器系统中,确保对共享资源的访问是安全、可靠和高效的操作。原子操作是指在执行某个操作时,不允许其他处理器或线程干扰或中断该操作,直到该操作完成。 ...

    atomic_ops原子操作1

    原子操作 atomic_ops 介绍 atomic_ops 是 Linux 内核中的一种原子操作,用于实现原子 counter、Bit 操作和 spinlock 接口。下面将对 atomic_ops 的原子操作进行详细介绍。 atomic_t 类型 atomic_t 是一种原子...

    C++中的原子操作:确保并发编程中的线程安全

    本文将详细介绍C++中的原子操作,包括其基本概念、使用场景、API以及如何利用原子操作来避免竞态条件和死锁。 原子操作是C++并发编程中的重要特性,它们为开发者提供了一种高效、灵活且线程安全的方法来处理并发问题...

    MongoDB原子操作.pdf

    在处理并发操作和数据更新时,MongoDB 提供了原子性保障,确保在单个文档级别的操作是不可分割的,即原子操作。虽然 MongoDB 不支持跨文档的事务,但对单个文档的修改、保存和删除等操作都是原子性的,保证了数据的...

    Linux驱动并发控制之位原子操作.pdf

    Linux 驱动并发控制之位原子操作 本文主要讲述 Linux 驱动并发控制中的位原子操作,包括其原理、常用的位原子操作函数、设备注册、驱动源码文件等。 一、位原子操作的原理 位原子操作是利用位操作来实现并发控制...

    linux下原子操作程序源码.zip

    在Linux系统中,原子操作(Atomic Operations)是编程中一种重要的技术,特别是在多线程和并发环境下,确保数据的一致性和完整性。它们提供了一种在不使用锁的情况下更新变量的方法,避免了竞态条件和死锁的问题。在...

    详解C++11原子类型与原子操作

    1.认识原子操作 原子操作就是在多线程程序中“最小的且不可并行化的”操作,意味着多个线程访问同一个资源时,有且仅有一个线程能对资源进行操作。通常情况下原子操作可以通过互斥的访问方式来保证,例如Linux下的...

    C++ 11 开发中的 Atomic 原子操作.rar_C++11、原子_atomic c++_c++ atomic使用_c++

    C++11引入了原子操作(Atomic Operations)作为标准库的一部分,这为多线程编程提供了重要的支持。原子操作在并发环境下确保了数据的完整性,防止了数据竞争和其他并发问题。下面将详细介绍C++11中`std::atomic`的...

    Java中的原子操作:深入探索AtomicInteger的实现与应用

    AtomicInteger 是Java并发编程中实现原子操作的重要工具。它通过 Unsafe 类提供的硬件级别的原子操作和 volatile 关键字保证了操作的原子性和可见性。在实际开发中,我们应该根据具体的应用场景选择合适的同步机制。...

Global site tag (gtag.js) - Google Analytics