程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言賦值語句是不是原子操作?

C語言賦值語句是不是原子操作?

編輯:關於C語言

經常看到有同學討論,C語言的賦值語句是不是原子操作?C語言的++語句是不是原子操作?

webopedia:
Atomic implies indivisibility and irreducibility, so an atomic operation must be performed entirely or not performed at all.
An operation during which a processor can simultaneously read a location and write it in the same bus operation. This prevents any other processor or I/O device from writing or reading memory until the operation is complete.

osdev:
An atomic operation is an operation that will always be executed without any other process being able to read or change state that is read or changed during the operation. It is effectively executed as a single step, and is an important quality in a number of algorithms that deal with multiple indepent processes, both in synchronization and algorithms that update shared data without requiring synchronization.

相關概念:
時鐘周期、總線周期和指令周期
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:

[cpp]
#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]
pushq   %rbp 
      movq    %rsp, %rbp 
      movl    $99, -4(%rbp) 
      movl    -4(%rbp), %eax 
      movl    %eax, -8(%rbp) 
      leave 
fun2相關指令:
[plain]
pushq   %rbp 
movq    %rsp, %rbp 
movl    $10, -4(%rbp) 
leaq    -4(%rbp), %rax 
incl    (%rax) 
movl    %eax, -4(%rbp) 
leave 

可以看到,n = m為兩條指令:
        movl    -4(%rbp), %eax
        movl    %eax, -8(%rbp)

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

總結:
原子操作和硬件實現、編譯器實現都緊密相關,因此,單純的在高級語言的層次討論原子操作,沒有太大的意義。


摘自 夜風的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved