多线程单例:实例方法是否需要互斥体?
Multi-thread singleton: does the instance method need a mutex?
我的应用程序配置存储在单例中 class,像这样(简化):
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;
};
因为配置class可以被多线程访问,所以我使用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];
}
Conf::instance()
方法是否也需要锁?
我发现了类似的问题:does a getter function need a mutex?,
但在我的例子中没有 setter 方法(假设单例实例是在线程启动之前创建的)。
在 C++11 中 instance()
不需要互斥量,在 C++98 中它需要互斥量,因为两个线程可能会同时进入它并开始构造对象。 C++11 确保 static
'local' 变量的单一初始化。
如果您使用的是 c++11 或更好的版本,静态单例的创建保证是线程安全的。
如果您仍在使用 c++03,那么您需要提供自己的机制。
根据要求:
c++11 标准第 6.7 节:
such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
脚注:
The implementation must not introduce any deadlock around execution of the initializer.
不这样使用,instance() 不需要互斥体。
但是我会通过在私有部分中移动实例来强制执行此操作,从而允许客户端代码仅使用 setProperty/getProperty.
我的应用程序配置存储在单例中 class,像这样(简化):
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;
};
因为配置class可以被多线程访问,所以我使用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];
}
Conf::instance()
方法是否也需要锁?
我发现了类似的问题:does a getter function need a mutex?, 但在我的例子中没有 setter 方法(假设单例实例是在线程启动之前创建的)。
在 C++11 中 instance()
不需要互斥量,在 C++98 中它需要互斥量,因为两个线程可能会同时进入它并开始构造对象。 C++11 确保 static
'local' 变量的单一初始化。
如果您使用的是 c++11 或更好的版本,静态单例的创建保证是线程安全的。
如果您仍在使用 c++03,那么您需要提供自己的机制。
根据要求:
c++11 标准第 6.7 节:
such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
脚注:
The implementation must not introduce any deadlock around execution of the initializer.
不这样使用,instance() 不需要互斥体。
但是我会通过在私有部分中移动实例来强制执行此操作,从而允许客户端代码仅使用 setProperty/getProperty.