簡體   English   中英

是否可以自動對 singleton object 線程安全進行原子操作

[英]Is it possible to make atomic operations on singleton object thread safe automatically

我有 singleton object 在兩個在單獨線程上運行的單元之間共享。 例如,

線程 A Singleton.getInstace().incCounter();

線程 B Singleton.getInstance().decCounter();

是否可以將這個原子實現為線程安全的,而不用打擾消費者以線程安全的方式進行操作。

就像是

static Singleton& GetInstance() {

    std::scoped_lock lock(m_mtx);

    static Singleton* singleton = new Singleton();

    return *singleton;
}

我想這不會起作用,因為鎖將在返回后被釋放,但 incCounter 和 decCounter 將在沒有鎖的情況下被調用。 是否有可能在原子操作完成之前保持鎖處於活動狀態。 在 incCounter 和 decCounter 內進行鎖定是這里唯一的解決方案或在單元 A 和單元 B 中的唯一解決方案。

當前的鎖什么也沒做。 C++ 標准要求在一個線程中初始化static函數局部變量。 也就是說,編譯器將確保在其初始化時不會出現競爭條件。 所以鎖可以防止一些不可能發生的事情。

您需要在遞增/遞減函數中加鎖。 他們需要鎖定同一個互斥鎖。 雖然也許他們可以增加/減少一個原子變量,在這種情況下你根本不需要鎖。

可以(但可能不應該)創建一個新類型LockedSingleton ,它存儲對 singletonstd::unique_lock的引用。 這將是您的GetInstance()返回的內容。 LockedSingleton需要有自己的遞增/遞減函數,它轉發到其內部 singleton 參考,以及任何其他接口函數。

class LockedSingleton
{
private:
  std::unique_lock<std::mutex> lock_;
  Singleton &obj_;

private: //Only friends can construct. Also, non-copyable.
  LockedSingleton(std::mutex &mtx, Singleton &obj)
    : lock_(mtx)
    , obj_(obj)
  {}

  friend Singleton& GetInstance();

public:

  void incCounter() {obj.incCounter();}
  void decCounter() {obj.decCounter();}
    
};

static LockedSingleton GetInstance() {
    static Singleton* singleton = new Singleton();

    return LockedSingleton(m_mtx, *singleton);
}

請注意,這僅適用於 C++17 及更高版本,由於保證省略,因為LockedSingleton是不可復制的。

暫無
暫無

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

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