【问题标题】:C++ Meyers Singleton - thread safe (code equivalent for mutex?)C ++ Meyers Singleton - 线程安全(互斥锁的代码等效?)
【发布时间】:2016-03-04 06:07:30
【问题描述】:

上周有人向我指出了这样一段代码:

#include <pthread.h>
namespace NSTest
{
class SingletonClass
{
public:


    static SingletonClass & getInstance()
    {
        static  pthread_mutex_t mutex;
        pthread_mutex_lock(&mutex);
        if(singletonPtr==nullptr)
        {
            createInstence();
        }
        return (*singletonPtr);
        pthread_mutex_unlock(&mutex);

    }

private:
    static void createInstence()
    {
        static SingletonClass static_SingletonClass;
        singletonPtr=&static_SingletonClass;

    }
    static SingletonClass * singletonPtr;

};

SingletonClass * SingletonClass::singletonPtr=nullptr;


class SingletonClassNoStatic
{
public:
    static SingletonClassNoStatic & getInstance()
    {
        pthread_mutex_lock(&mutex);
        if(singletonPtr==nullptr)
        {
            createInstence();
        }
        return (*singletonPtr);
        pthread_mutex_unlock(&mutex);
    }
private:
    static void createInstence()
    {
        static SingletonClassNoStatic static_SingletonClass;
        singletonPtr=&static_SingletonClass;

    }
    static SingletonClassNoStatic * singletonPtr;

    static  pthread_mutex_t mutex;
};
SingletonClassNoStatic * SingletonClassNoStatic::singletonPtr=nullptr;
pthread_mutex_t SingletonClassNoStatic::mutex;
}
int main()
{

    NSTest::SingletonClass::getInstance();
    NSTest::SingletonClassNoStatic::getInstance();

    return 0;
}

getInstance 方法被指出是正确的,原来是 getIntance(StaticMutex),编码不是线程安全的 (c++98),因为互斥锁是在方法中创建的,它是静态的并且使用静态互斥体,我遵循静态方法中的静态实例的规则是创建一次并且不再创建,但是这个规则因为不应用于互斥体。我有疑问,纠正可以吗?每个访问该方法(静态互斥锁)的线程都会创建自己的互斥锁?我正在阅读该操作仅针对来自类的方法的方法,但由于互斥锁是在静态方法中创建的静态方法,它将被创建一次。 我是否正确理解了这个概念?

【问题讨论】:

  • 请注意,在 C++11 中 getInstance() 是自动线程安全的,不需要任何互斥体 preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11
  • 您两次谈到 C++98,但直到 C++11 才添加 std::mutex(直到那时标准也不支持多线程)。
  • 对不起,我没有注意到这一点。编辑它
  • 在多线程开始之前显式地实例化单例。延迟初始化的真实用例非常罕见。或者,这通常是更可取的做法,完全放弃单例模式。这是一个伪装成 OOP 模式的全局变量。
  • “这种方法建立在 C++ 保证在调用该函数期间首次遇到对象定义时初始化本地静态对象。” ...“作为奖励,如果您从不调用模拟非本地静态对象的函数,则永远不会产生构造和破坏对象的成本。”它是否适用于在静态函数上作为静态变量创建的任何对象?

标签: c++ thread-safety singleton static-methods static-members


【解决方案1】:

在 C++11(由 std::mutex 暗示)中,整个 Meyers 单例用两行表示:

Singleton& instance() {
  static Singleton instance;

  return instance;
}

不需要其他任何东西。问题本身非常不清楚,因为您在同一上下文中谈论 C++98 和 std::mutex ,而这些并没有加起来。

发布代码的另一个问题是它不是一开始就是 Meyer 的单例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多