线程保护和函数内联

时间:2018-02-15 08:35:32

标签: multithreading c++11

我有以下锁和线程保护实现:

class Spinlock
{
public:
    /* Default constructor/destructor + deleted copy/moving */

    void Lock()
    {
        while (m_flag.test_and_set(std::memory_order_acquire))
        {
            // spin...
        };
    }

    void Unlock()
    {
        m_flag.clear(std::memory_order_release);
    }

private:
    std::atomic_flag m_flag = ATOMIC_FLAG_INIT;
};

template<class ThreadLock>
class ThreadGuard
{
public:
    /* Default constructor + deleted copy/moving */

    /* Constructor */
    ThreadGuard(ThreadLock& lock)
        : m_pLock(&lock)
    {
        m_pLock->Lock();
    }

    /* Destructor */
    ~ThreadGuard()
    {
        m_pLock->Unlock();
    }

private:
    ThreadLock* m_pLock;
};

现在,让我说我有以下代码:

void LockDataAndSetX()
{
   ThreadGuard lock(m_spinLock);
   /* ... operations on data here ...*/
}

{
   /* code... */

   LockDataAndSetX();

   /* more code...  */
}

我徘徊,如果编译器想要内联LockDataAndSetX函数,它会转换为下面的代码吗?

{
   /* code... */

   ThreadGuard lock(m_spinLock);
   /* ... operations on data here ...*/

   /* more code...  */

}

我问,因为这对我来说会有问题,因为锁定范围将取决于编译器内联/非内联锁定功能。在这种情况下,我需要删除我的线程保护类。

1 个答案:

答案 0 :(得分:2)

变量的范围/生命周期不依赖于内联。内联是一个优化问题,代码必须独立于编译器是否应用内联而具有相同的效果。

您可以想象内联的效果更像如下:

{
   /* code... */

   {
      ThreadGuard lock(m_spinLock);
      /* ... operations on data here ...*/
   }

   /* more code...  */
}

另请注意,ThreadGuard是一个模板,并且类的模板参数推导(基于构造函数参数)适用于C ++ 17。