[英]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
,它存儲對 singleton和std::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.