原子访问

线程同步一大部分与原子访问(atomic access)有关, 所谓原子访问, 指的是一个线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问同一资源.

假设编译器将g_x递增的那行代码时,生成了下面的汇编代码:

MOV EAX, [g_x] ;   Move the value in g_x into a register

INC EAX        ;   Increment the value in the register

MOV [g_x] , EAX;   Store the new value back in g_x

两个线程不太可能在完全相同的时刻执行上面的代码. 但如果是下面这样呢?

MOV EAX, [g_x]  ;  thread1: move 0 into a register

INC EAX         ;  thread1: Increment the register to 1

MOV EAX, [g_x]  ;  thread2: Move 0 into a register

INC EAX         ;  thread2: Increment the register to 1

MOV [g_x], EAX  ;  thread2: Store 1 back in g_x

MOV [g_x] , EAX ; thread 1 : Store 1 back in g_x.

结果显而易见,这是不正确的,多个线程访问同一资源的方式.

为了解决这个问题,需要一种方法能够保证对一个值的递增操作是原子操作---就是说,不会被打断,Interlocked系列函数为我们提供了这种解决方案,所有这些函数会以原子方式操作一个值.

原子访问

时间: 2024-10-29 01:17:03

原子访问的相关文章

[并发并行]_[线程同步]_[Windows用户态下的原子访问的互锁函数]

场景: 1. 多线程编程时,有时候需要统计某个变量或对象的创建个数或者是根据某个变量值来判断是否需要继续执行下去,这时候互锁函数是比较高效的方案之一了. 说明: 1.原子访问:(互锁函数族) -- 原子访问,指线程在访问资源时能够确保所有其他线程都不在同一时间内访问相同的资源. -- 调用一个互锁函数通常只需要执行几个CPU周期(通常小于50),并且不需要从用户模式转换为内核模式(通常这需要1000个CPU周期). -- 互锁函数是CPU硬件支持的,如果是x86处理器,互锁函数会向总线发出一个硬

windows线程同步之原子锁(原子访问)

原子锁(原子访问):一个线程在访问某个资源的同时必须确保其他线程不会同时访问此资源. 没有实现原子锁的结果: //定义一个全局变量 long g_lx = 0; DWORD WINAPI ThreadFunc1(PVOID pvParam){ for( int index=0; index<10000; index++ ) { g_lx++: //g_lx加1: } return 0: } DWORD WINAPI ThreadFunc2(PVOID pvParam){ for( int ind

Java自学-多线程 原子访问

多线程 原子访问 步骤 1 : 原子性操作概念 所谓的原子性操作即不可中断的操作,比如赋值操作 int i = 5; 原子性操作本身是线程安全的 但是 i++ 这个行为,事实上是有3个原子性操作组成的. 步骤 1. 取 i 的值 步骤 2. i + 1 步骤 3. 把新的值赋予i 这三个步骤,每一步都是一个原子操作,但是合在一起,就不是原子操作.就不是线程安全的. 换句话说,一个线程在步骤1 取i 的值结束后,还没有来得及进行步骤2,另一个线程也可以取 i的值了. 这也是分析同步问题产生的原因

【读书笔记】《Linux内核设计与实现》内核同步介绍&内核同步方法

简要做个笔记,以备忘. 需同步的原因是,我们并发访问了共享资源.我们将访问或操作共享资源的代码段称"临界区",如果两个执行线程处于同一临界区中同时执行,称"竞争条件".这里术语执行线程指任何正在执行的代码实例,如一个在内核执行的进程.一个中断处理程序或一个内核线程. 举个简单例子,i++操作.该操作可以转换为下面的机器指令序列: 1.得到当前变量i的值,并保存到一个寄存器. 2.将寄存器的值加1. 3.将i的新值写回到内存中. 当两个线程同时进入这个临界区,若i初值

[C/C++]_[中级]_[数据地址对齐]

场景: 1. 有些频繁使用的指针变量地址不对齐的话运行效率和对齐后的运行效率差别很大,所以在创建堆空间时,有必要对内存地址对齐提高运行效率. 2. 有些音视频处理的代码或者说自定义的malloc基本都是地址对齐的. 3. 使用原子访问的互锁函数时,InterlockedExchangeAdd都需要地址对齐. 4. 主要还是宏APR_ALIGN, 这个说是Apache源码里,就借用一下吧. 解决方案: 1. 其实就是让地址值对对齐量求模为0, 地址值最多增加n-1个偏移地址就可就可以整出n.  &

[翻译]在 .NET Core 中的并发编程

原文地址:http://www.dotnetcurry.com/dotnet/1360/concurrent-programming-dotnet-core 今天我们购买的每台电脑都有一个多核心的 CPU,允许它并行执行多个指令.操作系统通过将进程调度到不同的内核来发挥这个结构的优点.然而,还可以通过异步 I/O 操作和并行处理来帮助我们提高单个应用程序的性能.在.NET Core中,任务 (tasks) 是并发编程的主要抽象表述,但还有其他支撑类可以使我们的工作更容易. 并发编程 - 异步 v

第8章 用户模式下的线程同步

8.1 原子访问:Interlocked系列函数(Interlock英文为互锁的意思) (1)原子访问的原理 ①原子访问:指的是一线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问该资源. ②从汇编的角度看,哪怕很简单的一条高级语言都可以被编译成多条的机器指令.在多线程环境下,这条语句的执行就可能被打断.而在打断期间,其中间结果可能己经被其他线程更改过,从而导致错误的结果. ③在Intelx86指令体系中,有些运算指令加上lock前缀就可以保证该指令操作的原子性.其原理是CPU执行该指

Win32 - 线程同步

线程的同步可分用户模式的线程同步和内核对象的线程同步两大类. 用户模式中线程的同步方法主要有原子访问和临界区等方法.其特点是同步速度特别快,适合于对线程运行速度有严格要求的场合. 内核对象的线程同步则主要由事件.等待定时器.信号量以及信号灯等内核对象构成.由于这种同步机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,而这种转换一般要耗费近千个CPU周期,因此同步速度较慢,但在适用性上却要远优于用户模式的线程同步方式. 在WIN32中,同步机制主要有以下几种: (1)事件(Event)

JDK源码分析-AtomicInteger

AtomicInteger可以看做Integer类的原子操作工具类.在java.util.concurrent.atomic包下,在一些使用场合下可以取代加锁操作提高并发性.接下来就从几个方面来介绍: 1.原子性和CAS. 2.CPU底层实现原理. 3.atomic包介绍. 4.源码分析. 原子性和CAS 原子性就是指某一个操作是不可拆分的,是一个整体必须要一次性全部执行完成要么就不执行. CAS是Compare And Swap(比较并交换).意思是当你要更新某个值的时候先要检查这个变量的当前