boost::atomic 实现 spinlock

boost::atomic 实现 spinlock
先看下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实现的。



 VCZH.粉丝数组[0]<[email protected]>  21:49:07
atomic的 compare_exchange_weak
compare_exchange_weak
有啥区别

求解释
vczh.Iskandar<[email protected]>  21:49:27
不是一样吗
御虚舟北(314969051)  21:49:40
改代码中, ing
VCZH.粉丝数组[0]<[email protected]>  21:49:49
Windows上的实现是一样的
May fail spuriously, so must generally be retried in a loop. 
这一句怎么理解呢
vczh.Iskandar<[email protected]>  21:50:07
compare_exchange_weak
compare_exchange_weak
质量最大vczh粉(402740419)  21:50:14
compare_exchange_weak
compare_exchange_weak

VCZH.粉丝数组[0]<[email protected]>  21:50:16
strong

compare_exchange_strong
还有一个问题
class spinlock {
private:
  typedef enum {Locked, Unlocked} LockState;
  boost::atomic<LockState> state_;

public:
  spinlock() : state_(Unlocked) {}

  void lock()
  {
    while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) {
      /* busy-wait */
    }
  }
  void unlock()
  {
    state_.store(Unlocked, boost::memory_order_release);
  }
};

boost例子给的 spinloc
怎么是这样实现的
都没有用cae操作
VCZH.粉丝数组[0]<[email protected]>  21:51:20
unlock都直接用store了
vczh.Iskandar<[email protected]>  21:51:50
不用compare
VCZH.粉丝数组[0]<[email protected]>  21:51:59
 为啥
无法理解
vczh.Iskandar<[email protected]>  21:52:34
想要解释好麻烦
VCZH.粉丝数组[0]<[email protected]>  21:52:40
还有在Windows上
boost::memory_order_acquire
这个参数也没用
貌似
求V神解释
还有strong和weak的区别
质量最大vczh粉(402740419)  21:54:46
spinlock本来就不用compare啊
直接swap就行了
while (state_.swap(1) == 1);
VCZH.粉丝数组[0]<[email protected]>  21:56:24
你看假设现在是lock状态
boost的实现是无条件吧lock换成unlock
如果是继续lock 他还是lock
VCZH.粉丝数组[0]<[email protected]>  21:58:08
只要要避免 重入吧
lock之前检查一下
御虚舟北(314969051)  22:00:03
小康你的书收到没有
质量最大vczh粉(402740419)  22:03:17
VCZH.粉丝数组[0]<[email protected]>  21:58:08
只要要避免 重入吧
lock之前检查一下

你用错了他不管你
就是这个意思
同一个线程lock两次也会死锁
VCZH.粉丝数组[0]<[email protected]>  22:05:05
原来是这样

但是他lock的时候不检查,也会导致两个线程同时lock吧?
while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) {
      /* busy-wait */
    }

质量最大vczh粉(402740419)  22:05:18
不会啊
假设A进程先来了,lock成功了
VCZH.粉丝数组[0]<[email protected]>  22:05:33
怎能理解,我理解和直接赋值是一样
我再去看
质量最大vczh粉(402740419)  22:05:40
这不是复制
是exchange
swap
另一个线程exchange就会收到Locked
那么另一个线程就会while循环,直到原来线程给设置了Unlocked
VCZH.粉丝数组[0]<[email protected]>  22:06:47
Exchange current value with new_value, returning current value 

exchange是把新值写入旧值返回么?  不是这样么?
我有点理解了
质量最大vczh粉(402740419)  22:07:46
对啊,新值写入,旧值返回,原子的
VCZH.粉丝数组[0]<[email protected]>  22:07:59
就是说写入也是写入的lock, 不影响之前的lock
当前线程拿到旧值检查是不是lock状态,如果是就继续尝试直到不是
质量最大vczh粉(402740419)  22:08:00
所以只会有一个线程返回Unlocked,另一个线程会收到之前线程设置的Locked
VCZH.粉丝数组[0]<[email protected]>  22:08:11
 受教了
质量最大vczh粉(402740419)  22:08:13

VCZH.粉丝数组[0]<[email protected]>  22:08:20
我贴到博客上去 

你可能感兴趣的:(boost::atomic 实现 spinlock)