构造静态函数范围对象是否是线程安全的?

时间:2010-12-30 22:23:26

标签: c++

假设我有一个尝试使用此代码保护全局计数器的函数:

 static MyCriticalSectionWrapper lock;
 lock.Enter();
 counter = ++m_counter;
 lock.Leave();

两个线程是否有可能调用lock的构造函数?实现这一目标的安全方法是什么?

4 个答案:

答案 0 :(得分:4)

锁对象本身的创建不是线程安全的。如果多个线程在(几乎)同时进入函数,则可能会创建多个独立的锁定对象,具体取决于编译器。

此问题的解决方案是使用:

  • 操作系统保证一次初始化(对于锁定对象)
  • Double-checked locking(假设您的特定情况安全)
  • 锁定对象的线程安全单例
  • 对于您的具体示例,您可以使用线程安全互锁(例如,Windows的InterlockedIncrement()函数)操作来增加并完全避免锁定

答案 1 :(得分:1)

构造函数调用可以依赖于实现和/或执行环境,但这不是scoped_lock,因此不是问题。

我认为主要操作可以防止多线程访问。

(你知道,global for global,function static for function static。那个lock变量必须在与被保护对象相同的范围内定义。)

答案 2 :(得分:0)

原始示例代码:

 static MyCriticalSectionWrapper lock;
 lock.Enter();
 counter = ++m_counter;
 lock.Leave();

我意识到计数器代码可能只是一个占位符,但如果它实际上是你想要做的,你可以使用Windows函数“InterlockedIncrement()”来实现这一点。 例如:

 // atomic increment for thread safety
 InterlockedIncrement(&m_counter);
 counter = m_counter;

答案 3 :(得分:-1)

这取决于你的锁实现。