c++:我的单例的 getInstance() 方法是线程安全的吗?
我目前正在尝试使用 boost::mutex 编写一个线程安全的单例(至少在构造和销毁方面)。我读到 boost 互斥体无法静态初始化(我丢失了阅读它的链接,抱歉),所以为了解决这个问题,我尝试了这个,如果构造和销毁的线程安全性是:
static T& getInstance()
{
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
boost::mutex mutex;
boost::lock_guard lock(mutex);
#endif
static T instance;
return instance;
}
是线程安全的,还是应该使用 boost: :调用一次?与这种方法相比,提升一次会给我带来任何性能优势吗?
编辑: 好吧,我的第一个想法显然是不正确的。为了澄清问题。 boost::mutex 可以安全地静态初始化吗?像这样:
class Singleton
{
private:
static boost::mutex m_mutex;
public:
static Singleton & getInstance()
{
boost::lock_guard lock(m_mutex);
static T instance;
return instance;
}
};
这是一种可行的方法,还是实际上静态初始化 boost::mutex 不安全(这是我读到的)?
编辑2: 啊,顺便说一下,这是链接 http:// uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html
I am currently trying to write a threadsafe singleton (at least in terms of construction and destruction) using boost::mutex. I read that boost mutex can't be initialized statically(I lost the link where I read it, sorry) so to work around that I tried this, if threadsafety for construction and destruction is:
static T& getInstance()
{
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
boost::mutex mutex;
boost::lock_guard lock(mutex);
#endif
static T instance;
return instance;
}
is that threadsafe, or should I use boost::call_once? Will boost once give me any performance benefit over this approach?
EDIT:
Okay, my first idea was obviously not correct. To clearify the question. Can a boost::mutex safely be initialized statically? Like this:
class Singleton
{
private:
static boost::mutex m_mutex;
public:
static Singleton & getInstance()
{
boost::lock_guard lock(m_mutex);
static T instance;
return instance;
}
};
Is that a working approach or is it in fact not safe to init boost::mutex statically (which is what I read)?
EDIT2:
Ah, that was the link by the way http://uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于函数的每个入口都会创建自己的锁,因此锁将完全无用;任意数量的线程都可以进入该函数,锁定不同的锁,并同时开始处理静态数据。
您可以在文件(或类静态)范围内创建锁;这将确保它及时创建,前提是您不在
main()
之前启动线程。然而,即使在初始化静态数据之后,这也会序列化函数的条目。为什么不首先在文件(或类静态)范围内定义静态数据呢?
Since each entry to the function will create its own lock, the lock will be completely useless; any number of threads can enter the function, lock different locks, and start messing with the static data at the same time.
You could create the lock at file (or class static) scope; this would ensure it's created in time, provided that you don't start threads before
main()
. However, this would also serialize entry to the function even after the static data is initialized.Why not just define your static data at file (or class static) scope in the first place?
GCC 提供静态变量的线程安全初始化。
因此,如果您使用 GCC,则无需关心静态变量的正确初始化
GCC provides thread safe initialization of static variables.
So, if you use GCC you do not need to care about proper initialization of static variables
您确实需要使用锁定。但是,您提出的 boost::mutex 方案已被破坏,因为您在堆栈上分配互斥体,并且多个并发调用者将各自获得自己的互斥体。
You do need to use locking. However, the
boost::mutex
scheme you propose is broken since you allocate the mutex on the stack and multiple concurrent callers would each get their own mutex.尝试使用 Meyers Singleton 实现。
更多信息...
Try to use the Meyers Singleton implementation.
More info...