多线程单例:实例方法是否需要互斥锁?

use*_*761 3 c++ singleton multithreading mutex

我将应用程序的配置存储在单例类中,如下所示(简化):

class Conf
{
    Conf();
    Conf(const Conf&);
    Conf& operator=(const Conf&);
    ~Conf();

public:

    static Conf& instance() 
    {
        static Conf singleton;
        return singleton;
    };

    static void setProperty(const std::string& name,
                            const std::string& value);
    static std::string getProperty(const std::string& name);

private:

    QMutex _mutex;
    std::map<std::string, std::string> _properties;
};
Run Code Online (Sandbox Code Playgroud)

因为可以从许多线程访问配置类,所以我使用mutex进行同步:

void Conf::setProperty(const std::string& name,
                 const std::string& value)
{
    QMutexLocker(&Conf::instance()._mutex);
    Conf::instance()._properties[name]=value;
}

std::string Conf::getProperty(const std::string& name)
{
    QMutexLocker(&Conf::instance()._mutex);
    return Conf::instance()._properties[name];
}
Run Code Online (Sandbox Code Playgroud)

Conf::instance()方法是否还需要锁定?

我发现了类似的问题:getter函数是否需要互斥锁?,但在我的情况下,没有setter方法(假设在线程开始之前创建单例的实例).

Ric*_*ges 5

如果您使用的是c ++ 11或更高版本,则保证静态单例的创建是线程安全的.

如果您仍在使用c ++ 03,那么您需要提供自己的机制.

按要求:

c ++ 11标准的第6.7节:

第一次控制通过其声明时初始化这样的变量; 这样的变量在初始化完成后被认为是初始化的.[...]如果控件在初始化变量时同时进入声明,则并发执行应等待初始化完成.

脚注:

实现不得在执行初始化程序时引入任何死锁.