本文最后更新于:2024年5月7日 下午

操作系统中存在一旦执行则要么执行完成要么不能执行的操作,这类操作具有良好的并行安全特性,被称为原子操作

简介

原子操作(atomic operation)指的是由多步操作组成的一个操作。如果该操作不能原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。

现代操作系统中,一般都提供了原子操作来实现一些同步操作,所谓原子操作,也就是一个独立而不可分割的操作。在单核环境中,一般的意义下原子操作中线程不会被切换,线程切换要么在原子操作之前,要么在原子操作完成之后。更广泛的意义下原子操作是指一系列必须整体完成的操作步骤,如果任何一步操作没有完成,那么所有完成的步骤都必须回滚,这样就可以保证要么所有操作步骤都未完成,要么所有操作步骤都被完成。

在单核系统里,单个的机器指令可以看成是原子操作(如果有编译器优化、乱序执行等情况除外);在多核系统中,单个的机器指令就不是原子操作,因为多核系统里是多指令流并行运行的,一个核在执行一个指令时,其他核同时执行的指令有可能操作同一块内存区域,从而出现数据竞争现象。多核系统中的原子操作通常使用内存栅障(memory barrier)来实现,即一个CPU核在执行原子操作时,其他CPU核必须停止对内存操作或者不对指定的内存进行操作,这样才能避免数据竞争问题。

何时使用

在多线程并发的条件下,所有不是原子性的操作需要保证原子性时,都需要进行原子操作处理。

windows 原子操作 api

Win32 API中常用的原子操作主要有三类,一种是加1减1操作,一种是比较交换操作,另外一种是赋值(写)操作。

  1. 原子加1减1操作

    1
    2
    3
    LONG InterlockedIncrement( LONG volatile* Addend);

    LONG InterlockedDecrement( LONG volatile* Addend);
  2. 比较并交换(Compare And Swap, CAS)操作

    1
    LONG InterlockedCompareExchange( LONG volatile*Destination, LONG Exchange, LONG Comperand );

    这个操作是先将Comperand的值和Destination指向变量的值进行比较,如果相等就将Exchange变量的值赋给Destination指向的变量。返回值为未修改前的Destination位置的初始值。

  3. 原子写操作

    1
    LONG InterlockedExchange( LONG volatile* Target, LONG Value);

    InterlockedExchange的作用为将Value的值赋给Target指向的变量,返回Target指向变量未被赋值前的值。

并发安全

多线程

原子操作对于多线程并发是线程安全的,一个线程在执行原子操作时其他线程无法介入其中间过程,无法读、修改或打断该操作。

多进程

对于多进程也是有效的, 因为原子变量操作时是锁总线的,这个动作是在硬件层面来做的,他比操作系统更加底层,进程只是操作系统层面的概念,那么跨进程就更不再话下了。

参考资料



文章链接:
https://www.zywvvd.com/notes/coding/cpp/atomic-operation/atomic-operation/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

原子操作 Atomic Operation
https://www.zywvvd.com/notes/coding/cpp/atomic-operation/atomic-operation/
作者
Yiwei Zhang
发布于
2023年9月28日
许可协议