代码之家  ›  专栏  ›  技术社区  ›  danish sodhi

如何防止多线程在cpp中同时使用singleton类实例

  •  0
  • danish sodhi  · 技术社区  · 7 年前

    getInstance()

    class Singleton {
        Singleton() {}
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
     public:
        static Singleton& getInstance() {
            static Singleton s;
            return s;
        }
    };
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   NathanOliver    7 年前

    您可以做的一件事是通过锁定互斥锁来确保所有成员的线程安全。

    class Singleton {
        Singleton() {}
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
        std::mutex my_mutex_member;
     public:
        static Singleton& getInstance() {
            static Singleton s;
            return s;
        }
        void my_singleton_cool_function()
        {
            std::lock_guard<std::mutex> lg(my_mutex_member);
            // cool code here
        }
    };
    

    在上面的例子中 lg 将锁定互斥锁,并在函数结束时 被销毁,析构函数将解锁互斥锁。这意味着只有一个线程可以同时运行该函数。这允许所有线程都有一个对singleton的引用,并且只有当两个或多个线程试图同时做相同的事情时才会阻塞。

        2
  •  2
  •   Solomon Slow    7 年前

    我的问题是如何确保在特定时间只有一个线程在使用该实例。

    全体的 规则,你不能。

    但是,如果你的单身汉暴露了 public 数据成员,则所有赌注均已取消:您将无法控制其他模块如何“使用”对象的公共数据成员。


    当心即使您将所有数据成员都设置为私有,并将singleton对象设置为真正、真正的“线程安全”对象,也会 不保证其他代码的线程安全性,这些代码可能依赖于单例对象和其他数据之间的某种关系。

    invariant relationships . 例如,如果您有 doubly-linked ring p->next->prev 必须始终等于 p .

    要将新元素拼接到环中的螺纹必须暂时 打破 不变量。在这种情况下,“线程安全”意味着确保没有其他线程能够看到临时中断状态。

    用“线程安全”对象构建程序并不能使整个程序成为“线程安全”的,因为更高级别的程序可以依赖于对象之间重要的不变关系。而且,即使对象是 个别地 线程是安全的,它们无法意识到对整个程序有意义的更高级别的关系。

    推荐文章