如何确保只有1个互斥锁?

she*_*ill 2 c++ static synchronization mutex

我在这里运行一些线程安全的代码.我正在使用互斥锁来保护需要一次只运行1个线程的代码段.我遇到的问题是使用此代码有时我最终得到2个Mutex对象.顺便说一下,这是一个静态功能.如何确保只创建1个互斥对象?

/*static*/ MyClass::GetResource()
{

if (m_mutex == 0)
{
// make a new mutex object
m_mutex = new MyMutex();
}

m_mutex->Lock();
Run Code Online (Sandbox Code Playgroud)

Jus*_*cle 12

只需在可以被调用之前创建m_mutex外部GetResource(),- 这将删除实际创建互斥锁的关键部分.

MyClass::Init()
{
  m_mutex = new Mutex;
}    

MyClass::GetResource()
{
  m_mutex->Lock();
  ...
  m_mutex->Unlock();
}
Run Code Online (Sandbox Code Playgroud)

  • +1.试图创建懒惰的互斥会导致一个受伤的世界. (3认同)

Mic*_*ael 8

问题是在检查m_mutex是否为0之后线程可能被中断,但在创建互斥锁之前不会中断,允许另一个线程运行相同的代码.

不要立即分配给m_mutex.创建一个新的互斥锁,然后进行原子比较交换.

您没有提到您的目标平台,但在Windows上:

MyClass::GetResource()
{
    if (m_mutex == 0)
    {
        // make a new mutex object
        MyMutex* mutex = new MyMutex();

        // Only set if mutex is still NULL.
        if (InterlockedCompareExchangePointer(&m_mutex, mutex, 0) != 0)
        {
           // someone else beat us to it.
           delete mutex;
        }
    }
    m_mutex->Lock();
Run Code Online (Sandbox Code Playgroud)

否则,请使用平台提供的任何比较/交换功能进行替换.

另一种选择是使用一次性初始化支持,可以在Windows Vista及更高版本上使用,或者只是预先创建互斥锁(如果可以).