繁体   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