先看下boost给的例子,我觉得有问题: #include <boost/atomic.hpp> class spinlock { private: typedef enum {Locked, Unlocked} LockState; boost::atomic<LockState> state_; public: spinlock() : state_(Unlocked) {} void lock() { // 可能这里的boost::memory_order_acquire有原子操作的效果吧,偶不是很理解,不过我觉得这里应该用cae操作才对 while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) { /* busy-wait */ } } void unlock() { // 这里都直接写不做检查了,更加难以理解 state_.store(Unlocked, boost::memory_order_release); } };
自己实现:
class CESpinLock : boost::noncopyable
{
private:
typedef enum {emUnlocked = 0, emLocked} EM_LockState;
public:
CESpinLock() : m_atomicState(emLocked)
{
}
public:
void lock()
{
EM_LockState state = emUnlocked;
while(false == m_atomicState.compare_exchange_strong(state, emLocked))
{
state = emUnlocked;
}
}
void unlock()
{
EM_LockState state = emLocked;
while(false == m_atomicState.compare_exchange_strong(state, emUnlocked))
{
state = emLocked;
}
}
private:
boost::atomic<EM_LockState> m_atomicState;
};
可以适当的在false里边加一点sleep操作感觉。还有一点就是不太激烈这里的cae操作分两种 strong和weak
bool compare_exchange_weak(T & expected, T desired, memory_order success_order, memory_order failure_order)
Compare current value with expected
, change it to desired
if matches. Returns true
if an exchange has been performed, and always writes the previous value back in expected
. May fail spuriously, so must generally be retried in a loop.
bool compare_exchange_strong(T & expected, T desired, memory_order order)
Compare current value with expected
, change it to desired
if matches. Returns true
if an exchange has been performed, and always writes the previous value back in expected
. 实在不理解 May fail spuriously, so must generally be retried in a loop.的意义,不过看了代码,在win32的实现上,weak是调用了stong实现的。
有可能是我不理解后面的内存访问参数的意义,给下我自己的实现:
class CESpinLock : boost::noncopyable { private: typedef enum {emUnlocked = 0, emLocked} EM_LockState; public: CESpinLock() : m_atomicState(emLocked) { } public: void lock() { EM_LockState state = emUnlocked; while(false == m_atomicState.compare_exchange_strong(state, emLocked)) { state = emUnlocked; } } void unlock() { EM_LockState state = emLocked; while(false == m_atomicState.compare_exchange_strong(state, emUnlocked)) { state = emLocked; } } private: boost::atomic<EM_LockState> m_atomicState; };