2017-04-21 44 views
1

由于std::lock_guardstd::atomic_flag工作,我已经实现了我自己的版本:的std :: atomic_flag和std :: lock_guard

class atomic_guard { 
public: 
    inline atomic_guard(std::atomic_flag& lock) : lock(lock) { 
     while (this->lock.test_and_set()) { 
      /* spin */ 
     }; 
    }; 

    inline ~atomic_guard() { 
     this->lock.clear(); 
    }; 

private: 
    std::atomic_flag& lock; 
}; 

这似乎很好地工作。问题是:这是实施RAI的正确方法吗?还有一个内置的后卫吗?如果不是,为什么?专业std::lock_guard<std::atomic_flag>看起来很自然。

回答

1

如果使用atomic_guard作为独立的互斥量外观是正确的,但稍有不同。

使用std::atomic_flag直接使用std::lock_guard是不可能的,因为std::lock_guard模板管理互斥锁,而std::atomic_flag是(低级别)原子布尔类型。

可以与std::lock_guard使用mutex的实现必须提供的成员函数lockunlock,可以这样实现:

class my_mutex { 
    std::atomic_flag flag{ATOMIC_FLAG_INIT}; 

public: 
    void lock() 
    { 
     while (flag.test_and_set()); 
    } 

    void unlock() 
    { 
     flag.clear(); 
    } 
}; 

注意,这是一个非常基本的和低效的互斥执行,但它是与std::lock_guard兼容:

my_mutex mtx; 

std::lock_guard<my_mutex> lck{mtx}; 
+0

“低效率”是什么意思?标准互斥是不是更有效率的atomic_flag?至少在某些情况下,例如当锁定时间应该是短暂的。 – freakish

+0

@freakish如果一个线程正在等待使用'my_mutex'来获取锁,那么它正在浪费很多CPU时间,因为它在繁忙的while循环中 – LWimsey

+0

我不会称之为“浪费”。你获得执行时间,所以它是一个交易。看起来atomic_flag甚至可以比标准互斥量快50倍。所以如果你锁定很短的时间,那么“浪费”这些CPU周期可能是值得的。这里是基准测试:https://www.arangodb.com/2015/02/comparing-atomic-mutex-rwlocks/当然,我会在我的场景中进行适当的测试,但我预计至少会有2x加速。 – freakish

相关问题