先看下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有原子操作的效果吧,偶不是很理解,不過我覺得這里應(yīng)該用cae操作才對 while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) { /* busy-wait */ } } void unlock() {
// 這里都直接寫不做檢查了,更加難以理解 state_.store(Unlocked, boost::memory_order_release); } };
有可能是我不理解后面的內(nèi)存訪問參數(shù)的意義,給下我自己的實現(xiàn):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;
};
可以適當(dāng)?shù)脑趂alse里邊加一點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的實現(xiàn)上,weak是調(diào)用了stong實現(xiàn)的。
atomic的 compare_exchange_weak
compare_exchange_weak
有啥區(qū)別
SC5BVG@Z77TFAZI3REO[}R.gif)
求解釋
vczh.Iskandar<vczh@163.com> 21:49:27
不是一樣嗎
御虛舟北(314969051) 21:49:40
改代碼中, ing
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:49:49
Windows上的實現(xiàn)是一樣的
May fail spuriously, so must generally be retried in a loop.
這一句怎么理解呢
vczh.Iskandar<vczh@163.com> 21:50:07
compare_exchange_weak
compare_exchange_weak
質(zhì)量最大vczh粉(402740419) 21:50:14
compare_exchange_weak
compare_exchange_weak
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 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
怎么是這樣實現(xiàn)的
都沒有用cae操作
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:51:20
unlock都直接用store了
vczh.Iskandar<vczh@163.com> 21:51:50
不用compare
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:51:59
\Tencent\QQ\PersonalData\85126585\Image\Image3\HY)ZO7GDOQ)]Q8H(Q}8WQ~S.gif)
無法理解
vczh.Iskandar<vczh@163.com> 21:52:34
想要解釋好麻煩
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:52:40
還有在Windows上
boost::memory_order_acquire
這個參數(shù)也沒用
貌似
AJTFW.gif)
還有strong和weak的區(qū)別
質(zhì)量最大vczh粉(402740419) 21:54:46
spinlock本來就不用compare啊
直接swap就行了
while (state_.swap(1) == 1);
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:56:24
你看假設(shè)現(xiàn)在是lock狀態(tài)
boost的實現(xiàn)是無條件吧lock換成unlock
如果是繼續(xù)lock 他還是lock
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:58:08
只要要避免 重入吧
lock之前檢查一下
御虛舟北(314969051) 22:00:03
小康你的書收到?jīng)]有
質(zhì)量最大vczh粉(402740419) 22:03:17
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 21:58:08
只要要避免 重入吧
lock之前檢查一下
你用錯了他不管你
就是這個意思
同一個線程lock兩次也會死鎖
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:05:05
\Tencent\QQ\PersonalData\85126585\Image\Image3\HY)ZO7GDOQ)]Q8H(Q}8WQ~S.gif)
但是他lock的時候不檢查,也會導(dǎo)致兩個線程同時lock吧?
while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) {
/* busy-wait */
}
質(zhì)量最大vczh粉(402740419) 22:05:18
不會啊
假設(shè)A進(jìn)程先來了,lock成功了
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:05:33
怎能理解,我理解和直接賦值是一樣
我再去看
質(zhì)量最大vczh粉(402740419) 22:05:40
這不是復(fù)制
是exchange
swap
另一個線程exchange就會收到Locked
那么另一個線程就會while循環(huán),直到原來線程給設(shè)置了Unlocked
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:06:47
Exchange current value with new_value, returning current value
exchange是把新值寫入舊值返回么? 不是這樣么?
我有點理解了
質(zhì)量最大vczh粉(402740419) 22:07:46
對啊,新值寫入,舊值返回,原子的
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:07:59
就是說寫入也是寫入的lock, 不影響之前的lock
當(dāng)前線程拿到舊值檢查是不是lock狀態(tài),如果是就繼續(xù)嘗試直到不是
質(zhì)量最大vczh粉(402740419) 22:08:00
所以只會有一個線程返回Unlocked,另一個線程會收到之前線程設(shè)置的Locked
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:08:11
受教了
質(zhì)量最大vczh粉(402740419) 22:08:13
恩
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com> 22:08:20
我貼到博客上去