Rust Ordering語義理解
應用場景/條件
- 應用場景: 多線程之間使用原子類型通過共享內存的方式進行線程間通信;
- 使用條件: 支持原子類型操作的指令集架構平台, 如
x86/x86_64
支持LOCK
前綴的指令是原子操作;
注: 使用條件僅僅針對Rust, 當前1.43.1版本中Rust的所有Atomic**
實現中都加了#[cfg(target_has_atomic_load_store = "8")]
屬性配置;
為什么需要內存順序?
- 一些編譯器有指令重排功能以優化代碼執行效率, 在不同線程中針對同一變量(內存)的讀寫順序可能會被打亂, 不能保證順序的一致性;
- 一些處理器中有Cache緩存, 對某一內存的讀取可能是從緩存中直接讀取, 因此不同線程對同一變量的讀寫順序亦不能保證一致性;
原子內存順序
Rust原子操作操作有5中內存順序: Relaxed/Release/Acquire/AcqRel/SeqCst
, 下面一一介紹;
Relaxed
沒有內存順序約束, 僅僅是原子類型的本條store/load
操作是原子操作, 即針對該原子類型的在不同線程之間的操作順序是任意的;
Release/Acquire
Release
和Acquire
是在不同的線程間針對同一原子類型對象的進行store
和load
操作時配合使用. 當一個線程store
withRelease
寫原子類型對象, 而有另一個線程load
withAcquire
度原子類型對象時, 那么在寫及寫之前的所有寫原子操作都是發生在另一個線程中讀該原子類型之后的所有讀原子操作之前.
簡而言之就是, Release
之前的寫原子操作先於Acquire
之后的讀原子操作;
AcqRel
和Release/Acquire的效果一樣, 只不過是讀的時候使用Acquire
順序, 寫的時候使用Release
順序;
SeqCst
若某一原子類型對象在不同線程中使用SeqCst
讀寫, 那么該原子操作之前的所有讀寫原子操作都先於該原子操作之后的讀寫操作
參考資料
- The Rust Standard Library Version 1.43.1;
- cppreference std::memory_order;