首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

C语言的赋值++是不是为原子操作

2013-11-04 
C语言的赋值++是否为原子操作相关概念:时钟周期、总线周期和指令周期1.时钟周期:微处理器执行指令的最小时

C语言的赋值++是否为原子操作
相关概念:
时钟周期、总线周期和指令周期
1.时钟周期:微处理器执行指令的最小时间单位,又称T状态。它通常与微机的主频有关。
2.总线周期:CPU对存储器或I/O端口完成一次读/写操作所需的时间。如8086微处理器的基本总线周期由四个时钟周期T1~T4组成,80486微处理器的基本总线周期由T1和T2两个时钟周期组成。当外设速度较慢时,可插入等待周期Tw。
3.指令周期:CPU执行一条指令所需要的时间。指令周期由若干个总线周期组成,不同指令执行的时间不同。同一功能的指令,在寻址方式不同时,所需要的时间也不同。

总线操作周期:微机系统各部件之间的信息交换是通过总线操作周期完成的,一个总线周期通常分为以下四个阶段。
1.总线请求和仲裁阶段:当有多个模块提出总线请求时,必须由仲裁机构仲裁,确定将总线的使用权分配给哪个模块。
2.寻址阶段:取得总线使用权的模块,经总线发出本次要访问的存储器或I/O端口的地址和有关命令。
3.传送数据阶段:主模块(指取得总线控制权的模块)与其他模块之间进行数据的传送。
4.结束阶段:主模块将有关信息从总线上撤除,主模块交出对总线的控制权。

CPU最小的执行单元是指令,一个指令周期可能包括多个总线周期。
我们可以得到:
1. 在单处理器下,一个操作只包括一个cpu指令可以保证是原子操作。如果一个操作包含多个cpu指令不是原子操作。
2. 在多处理器下,由于一个cpu指令周期可能包含多个总线周期,就有可能出现其他处理器在一个指令执行期间访问了其相关的状态。因此,多处理器下,指令执行期间还必须锁总线,才能保证CPU指令的原子性


我们看下C语言的赋值和++操作

代码main.c:

  • #include <stdio.h>    
  • void fun1()  {  
  •         volatile int m;          volatile int n;  
  •         m = 99;          n = m;  
  • }    
  • void fun2()  {  
  •         volatile int n = 10;          n++;  
  • }    
  • int main(int argc, char** argv)  {  
  •         fun();    
  •         return 0;  }  汇编:
    gcc -S main.c
    查看fun1相关的指令:
    [plain] view plaincopy
    1. pushq   %rbp        movq    %rsp, %rbp  
    2.       movl    $99, -4(%rbp)        movl    -4(%rbp), %eax  
    3.       movl    %eax, -8(%rbp)        leave  
    fun2相关指令:
    [plain] view plaincopy
    1. pushq   %rbp  movq    %rsp, %rbp  
    2. movl    $10, -4(%rbp)  leaq    -4(%rbp), %rax  
    3. incl    (%rax)  movl    %eax, -4(%rbp)  
    4. leave  

    可以看到,n = m为两条指令:
            movl    -4(%rbp), %eax
            movl    %eax, -8(%rbp)

    n++三条指令:
             leaq    -4(%rbp), %rax
             incl    (%rax)  
             movl    %eax, -4(%rbp)
    都是多条指令,所以,不是原子操作。

    总结:

    原子操作和硬件实现、编译器实现都紧密相关,因此,单纯的在高级语言的层次讨论原子操作,没有太大的意义。

    但是在操作系统中还是会介绍有这个概念的讲解,到时候留心分析

  • 热点排行
    Bad Request.