C++20引入的std::atomic_ref是什么 原子引用對(duì)內(nèi)存模型的影響

std::atomic++_ref 是 c++20 中用于對(duì)非原子類(lèi)型變量進(jìn)行原子操作的模板類(lèi)。1. 它允許臨時(shí)以原子方式訪問(wèn)非原子變量,而無(wú)需將其聲明為 std::atomic;2. 常用于結(jié)構(gòu)體字段原子更新、與第三方庫(kù)交互等場(chǎng)景;3. 使用時(shí)必須確保對(duì)象對(duì)齊正確且同一時(shí)間只有一個(gè)線程進(jìn)行寫(xiě)操作;4. 應(yīng)避免長(zhǎng)期持有 atomic_ref 實(shí)例,不應(yīng)重復(fù)封裝已為原子類(lèi)型的變量;5. 內(nèi)存順序選擇影響程序行為,需謹(jǐn)慎選用如 memory_order_acq_rel 等順序以保證同步正確;6. 多線程下通過(guò)不同 atomic_ref 修改同一變量會(huì)導(dǎo)致未定義行為,需嚴(yán)格控制使用方式。

C++20引入的std::atomic_ref是什么 原子引用對(duì)內(nèi)存模型的影響

std::atomic_ref 是 C++20 中引入的一個(gè)新特性,它的作用是讓你對(duì)一個(gè)原本非原子類(lèi)型的變量進(jìn)行原子操作,而無(wú)需將該變量本身定義為 std::atomic。簡(jiǎn)單來(lái)說(shuō),它提供了一種臨時(shí)的、局部的原子訪問(wèn)方式。

C++20引入的std::atomic_ref是什么 原子引用對(duì)內(nèi)存模型的影響

這個(gè)特性在多線程編程中非常有用,尤其是在你想對(duì)某些共享數(shù)據(jù)進(jìn)行原子操作,但又不希望或不能將其聲明為原子類(lèi)型的情況下。

C++20引入的std::atomic_ref是什么 原子引用對(duì)內(nèi)存模型的影響


什么是 std::atomic_ref?

std::atomic_ref 是一個(gè)模板類(lèi),用來(lái)包裝一個(gè)類(lèi)型為 T 的對(duì)象,并允許你以原子的方式對(duì)其進(jìn)行讀寫(xiě)操作。與 std::atomic 不同的是,它并不擁有被引用的對(duì)象,只是對(duì)其做一個(gè)“原子視角”的封裝。

立即學(xué)習(xí)C++免費(fèi)學(xué)習(xí)筆記(深入)”;

舉個(gè)例子:

C++20引入的std::atomic_ref是什么 原子引用對(duì)內(nèi)存模型的影響

int x = 0; std::atomic_ref<int> ref(x); ref.store(42, std::memory_order_relaxed);

上面這段代碼讓變量 x 在被 atomic_ref 引用時(shí),可以進(jìn)行原子操作。但要注意:多個(gè)線程同時(shí)通過(guò)不同的 atomic_ref 修改同一個(gè)變量是未定義行為(UB),必須確保只有一個(gè)線程在使用 atomic_ref 進(jìn)行寫(xiě)操作。


使用場(chǎng)景和限制

常見(jiàn)用途:

  • 對(duì)結(jié)構(gòu)體中的某個(gè)字段做原子更新。
  • 與第三方庫(kù)交互時(shí),對(duì)方提供了非原子變量,但你希望安全地并發(fā)訪問(wèn)
  • 避免因?yàn)槭褂?std::atomic 而帶來(lái)的內(nèi)存對(duì)齊或性能開(kāi)銷(xiāo)。

限制條件:

  • 所引用的對(duì)象必須具有合適的對(duì)齊方式(通常需要是 T 的自然對(duì)齊)。
  • 同一時(shí)間只能有一個(gè)線程通過(guò) atomic_ref 修改對(duì)象。
  • 不建議長(zhǎng)期持有 atomic_ref 實(shí)例,應(yīng)該在需要的時(shí)候構(gòu)造并立即使用。

對(duì)內(nèi)存模型的影響

使用 std::atomic_ref 時(shí),你需要指定內(nèi)存順序(如 memory_order_relaxed, memory_order_acquire 等),這些順序會(huì)影響編譯器和 CPU 的優(yōu)化方式,進(jìn)而影響程序的行為。

例如:

std::atomic_ref<int> ref(x); ref.fetch_add(1, std::memory_order_acq_rel);

這里用了 acq_rel,意味著:

  • 操作前不會(huì)發(fā)生重排序(獲取語(yǔ)義)。
  • 操作后也不會(huì)讓后續(xù)操作提前執(zhí)行(釋放語(yǔ)義)。

因此,使用 atomic_ref 時(shí)選擇正確的 memory order 很重要,否則可能引發(fā)數(shù)據(jù)競(jìng)爭(zhēng)或違反預(yù)期的同步行為。


使用注意事項(xiàng)

  • 生命周期管理:確保 atomic_ref 所引用的對(duì)象在其生命周期內(nèi)有效。
  • 避免重復(fù)封裝:不要把已經(jīng)是一個(gè) std::atomic 的變量再封裝成 atomic_ref。
  • 跨線程使用要小心:不同線程不應(yīng)該同時(shí)用各自的 atomic_ref 修改同一變量。
  • 對(duì)齊問(wèn)題:有些平臺(tái)對(duì)原子操作有嚴(yán)格的對(duì)齊要求,否則會(huì)崩潰或行為異常。

基本上就這些。std::atomic_ref 是一個(gè)強(qiáng)大但容易誤用的工具,適用于特定的并發(fā)場(chǎng)景。掌握好它的使用規(guī)則,才能真正發(fā)揮它的價(jià)值。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊14 分享