zoukankan      html  css  js  c++  java
  • i++是否原子操作

    i++是否原子操作

    不是原子操作。理由:

    1.i++分为三个阶段:

    内存到寄存器

    寄存器自增

    回内存

    这三个阶段中间都可以被中断分离开.

     2.++i首先要看编译器是怎么编译的

    某些编译器比如VC在非优化版本中会编译为以下汇编代码:

    __asm
    {
            moveax,  dword ptr[i]
            inc eax
            mov dwordptr[i], eax
    }
    这种情况下,必定不是原子操作,不加锁互斥是不行的。

    假设加了优化参数,那么是否一定会编译为“inc dword ptr[i]”呢?答案是否定的,这要看编译器心情,如果++i的结果还要被使用的话,那么一定不会被编译为“inc dword ptr[i]”的形式。
    那么假设如果编译成了“inc dword ptr[i]”,这是原子操作,是否就不需要加锁了呢?如果在单核机器上,不加锁不会有问题,但到了多核机器上,这个不加锁同样会带来严重后果,两个CPU可以同时执行inc指令,但是两个执行以后,却可能出现只自加了一次。

    真正可以确保不“额外”加锁的汇编指令是“lock inc dword ptr[i]”,lock前缀可以暂时锁住总线,这时候其他CPU是无法访问相应数据的。但是目前没有任何一个编译器会将++int编译为这种形式。

    注释:

    汇编当中 dword ptr [ ] 是什么意思

    dword 双字 就是四个字节
    ptr pointer缩写 即指针
    []里的数据是一个地址值,这个地址指向一个双字型数据
    比如mov eax, dword ptr [12345678] 把内存地址12345678中的双字型(32位)数据赋给eax

  • 相关阅读:
    1.4 Arduino IDE
    1.3 选择适合的Arduino
    1.2为什么选择Arduino
    1.1什么是Arduino
    博文《arduino入门》预告
    Delphi实现HTMLWebBrowser实现HTML界面
    Delphi判断MDI子窗体是否被创建
    Delphi给窗体镶边-为控件加边框,描边,改变边框颜色
    Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄
    DELPHI实现类似仿360桌面的程序界面
  • 原文地址:https://www.cnblogs.com/lxd2502/p/4648020.html
Copyright © 2011-2022 走看看