簡體   English   中英

內存順序放寬的原子加載和存儲

[英]Atomic load and store with memory order relaxed

在我讀到的任何地方,我都看到強烈建議不要使用寬松的內存順序,我想知道以下代碼是否是可以工作的例外之一,或者有任何我沒有看到的后果。

class SessionHolder {
public:

  void set_session(std::shared_ptr<Session> session) {
    std::atomic_store_explicit(&_session, session, std::memory_order_relaxed);
  }

  std::shared_ptr<Session> get_session() const {
    return std::atomic_load_explicit(&_session, std::memory_order_relaxed);
  }

private:

  std::shared_ptr<Session> _session;
};

原則上,當我執行get_session ,我不在乎我得到哪個會話,只要它是會話或 nullptr。 但是,如果另一個線程進行存儲(這種情況很少發生),我希望最終在合理的延遲內獲得該值。

  • 據我所知,甚至不能保證我會得到那個值,只是我會得到一個在某個時間點存儲在那里的值,但我總是可以得到 nullptr。
  • 在實踐中似乎可行,我可以期望它在某些情況/平台下失敗(總是檢索 nullptr)嗎?
  • 我可以在存儲操作中調整內存順序來解決這個問題嗎? 例如memory_order_release會將更改傳播到另一個線程?

有關如何使用此類的更多上下文:

基本上,我有某種不斷產生數據的流。 在某個時刻,客戶端進程可能會連接(啟動會話)並開始偵聽此數據。 生產者線程不斷地寫入流,如果沒有活動會話,則數據被丟棄,否則發送到客戶端。 另一個線程,在某個時間點(不經常),當客戶端連接到這個流並設置會話時。

生產者線程必須有盡可能少的爭用,即使這意味着丟失一些消息。

據我所知,甚至不能保證我會得到那個值,只是我會得到一個在某個時間點存儲在那里的值,但我總是可以得到 nullptr。

是的,假設每次調用get_session都可能返回空指針,但不太可能。 即使是寬松的內存順序提供的一種保證是,一旦特定線程觀察到一個值,同一個線程隨后就無法觀察到先前的值。 因此,一旦特定線程開始觀察非空指針,該線程將始終在對get_session后續調用中觀察非空指針(假設從未存儲空指針)。

在實踐中似乎可行,我可以期望它在某些情況/平台下失敗(總是檢索 nullptr)嗎?

不是我所知道的。

我可以在存儲操作中調整內存順序來解決這個問題嗎? 例如memory_order_release會將更改傳播到另一個線程?

不可以。該標准沒有提供任何方法來確保在任何特定時間內完成線程間通信。 只有實現才能提供這樣的保證。

最后一點: nullptr與“空指針”不同。 它是一種獨特類型的特殊常量,可以轉換為另一種類型的空指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM