簡體   English   中英

在多線程中返回 shared_ptr 是否安全?

[英]Returning shared_ptr in multithreading is safe?

我剛剛開始使用 c++ 在多線程環境中工作。我對下面的代碼片段有疑問。

std::shared_ptr<SomeInterface> getSessionLocked(const std::string& token) {
          std::lock_guard<std::mutex> guard(m_mutex);
           if (!findSessionByToken(token)) {
               return nullptr;
          }
          return m_activeSessions[token]; 
    }
bool findSessionByToken(const std::string& token) {
      return !(m_activeSessions.find(token) == m_activeSessions.end());
 }

m_mutex 和 m_activeSessions 都是私有變量。現在我的問題是“返回這樣的共享指針是否安全”,因為我認為由於競爭條件可能存在數據不一致的可能性。 有人可以清除這件事嗎?

這個功能:

std::shared_ptr<SomeInterface> getSessionLocked(const std::string& token) {
      std::lock_guard<std::mutex> guard(m_mutex);
       if (!findSessionByToken(token)) {
           return nullptr;
      }
      return m_activeSessions[token]; 
}

沒關系,因為:

  1. 除非您有鎖,否則您不會從m_activeSessions讀取
  2. 您返回std::shared_ptr ,因此在對該共享指針的所有引用超出范圍之前,該對象不會被銷毀(即使您從m_activeSessions中刪除了令牌。

有人認為這可能會更好/您需要注意:

  1. 考慮速率 #readers / #writers 以查看您是否需要讀寫器鎖。
  2. 如果認為很難跟蹤可能使用共享指針的所有不同位置,請考慮使用std::weak_ptr

另一方面,這個函數:

bool findSessionByToken(const std::string& token) {
    return !(m_activeSessions.find(token) == m_activeSessions.end());
}

不是線程安全的( find返回的迭代器可能在比較發生之前失效)。

現在,在您的示例中,該函數是在持有鎖的情況下調用的:這個函數是公共的還是私有的?

如果這是一個私有函數,那沒關系,但我建議更改名稱以反映不是線程安全的事實(帶有UnlockedUnsafe后綴的東西)。

如果這個函數是公開的,那么你就有問題了。

最后,該函數返回bool ,因此名稱應該類似於containsTokencontainsTokenUnsafe find一詞表示您將返回會話,但您沒有。

最后的想法:

考慮到這是一個多線程應用程序,需要同時訪問共享資源,我會將並發作為一等公民並更改命名法:

  • getSession getSessionLocked 不僅因為上面的原因,還因為調用者不應該關心你是否使用鎖。 我的意思是,外部用戶將如何處理對類私有數據的不受保護的訪問?
  • 使非線程安全函數至少是私有的(添加 unsafe/unlocked 后綴可能是個人喜好)。

暫無
暫無

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

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