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
我贴到博客上去
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
我贴到博客上去