青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Error

C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
  217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks
先看下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ù)的意義,給下我自己的實(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里邊加一點(diǎn)sleep操作感覺。

還有一點(diǎn)就是不太激烈這里的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

實(shí)在不理解 May fail spuriously, so must generally be retried in a loop.的意義,不過看了代碼,在win32的實(shí)現(xiàn)上,weak是調(diào)用了stong實(shí)現(xiàn)的。



 VCZH.粉絲數(shù)組[0]<errorcpp@qq.com>  21:49:07
atomic的 compare_exchange_weak
compare_exchange_weak
有啥區(qū)別

求解釋
vczh.Iskandar<vczh@163.com>  21:49:27
不是一樣嗎
御虛舟北(314969051)  21:49:40
改代碼中, ing
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com>  21:49:49
Windows上的實(shí)現(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
怎么是這樣實(shí)現(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
 為啥
無法理解
vczh.Iskandar<vczh@163.com>  21:52:34
想要解釋好麻煩
VCZH.粉絲數(shù)組[0]<errorcpp@qq.com>  21:52:40
還有在Windows上
boost::memory_order_acquire
這個參數(shù)也沒用
貌似
求V神解釋
還有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的實(shí)現(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
原來是這樣

但是他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是把新值寫入舊值返回么?  不是這樣么?
我有點(diǎn)理解了
質(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
我貼到博客上去 

posted on 2013-03-31 21:49 Enic 閱讀(3805) 評論(1)  編輯 收藏 引用 所屬分類: cpp 1x and boost

評論

# re: boost::atomic 實(shí)現(xiàn) spinlock 2013-03-31 23:52 Enic
老外是這么說的:

http://cbloomrants.blogspot.be/2011/07/07-14-11-compareexchangestrong-vs.html


07-14-11 - compare_exchange_strong vs compare_exchange_weak

The C++0x standard was revised a while ago to split compare_exchange (aka CAS) into two ops. A quick note on the difference :

bool compare_exchange_weak( T * ptr, T * old, T new );

bool compare_exchange_strong( T * ptr, T * old, T new );

(BTW in the standard "old" is actually a reference, which is a damn shitty thing to do because it makes it very non-transparent that "old" gets mutated by these functions, so I am showing it as a pointer).
both try to do :


atomically {
if ( *ptr == *old ) { *ptr = new; return true; }
else { *old = *ptr; return false; }
}

the difference is that compare_exchange_weak can also return false for spurious failure. (the original C++0x definition of CAS always allowed spurious failure; the new thing is the _strong version which doesn't).
If it returns due to spurious failure, then *old might be left untouched (and in fact, *ptr might be equal to *old but we failed anyway).

If spurious failure can only occur due to contention, then you can still gaurantee progress. In fact in the real world, I believe that LL-SC architectures cannot gaurantee progress, because you can get spurious failure if there is contention anywhere on the cache line, and you need that contention to be specifically on your atomic variable to gaurantee progress. (I guess if you are really worried about this, then you should ensure that atomic variables are padded so they get their own cache line, which is generally good practice for performance reasons anyway).

On "cache line lock" type architectures like x86, there is no such thing as spurious failure. compare_exchange just maps to "cmpxchg" instruction and you always get the swap that you want. (it can still fail of course, if the value was not equal to the old value, but it will reload old). (BTW it's likely that x86 will move away from this in the future, because it's very expensive for very high core counts)

compare_exchange_weak exists for LL-SC (load linked/store conditional) type architectures (Power, ARM, basically everything except x86), because on them compare_exchange_strong must be implemented as a loop, while compare_exchange_weak can be non-looping. For example :

On ARM, compare_exchange_weak is something like :

compare_exchange_weak:

ldrex // load with reservation
teq // test equality
strexeq // store if equal
and strexeq can fail for two reasons - either because they weren't equal, or because the reservation was lost (because someone else touched our cache line).
To implement compare_exchange_strong you need a loop :

compare_exchange_strong:

while ( ! compare_exchange_weak(ptr,old,new) ) { }

(note that you might be tempted to put a (*old = *ptr) inside the loop, but that's probably not a good idea, and not necessary, because compare_exchange_weak will eventually load *ptr into *old itself when it doesn't fail spuriously).
The funny bit is that when you use compare_exchange you often loop anyway. For example say I want to use compare_exchange_strong to increment a value, I have to do :


cur = *ptr;
while( ! compare_exchange_strong(ptr,&cur,cur+1) ) { }

(note it's a little subtle that this works - when compare_exchange_strong fails, it's because somebody else touched *ptr, so we then reload cur (this is why "old" is passed by address), so you then recompute cur+1 from the new value; so with the compare_exchange_strong, cur has a different value each time around this loop.)
But on an LL-SC architecture like ARM this becomes a loop on a loop, which is dumb when you could get the same result with a single loop :


cur = *ptr;
while( ! compare_exchange_weak(ptr,&cur,cur+1) ) { }

Note that with this loop now cur does *not* always take a new value each time around the loop (it does when it fails due to contention, but not when it fails just due to reservation-lost), but the end result is the same.
So that's why compare_exchange_weak exists, but you might ask why compare_exchange_strong exists. If we always use loops like this, then there's no need for it. But we don't always use loops like this, or we might want to loop at the much higher level. For example you might have something like :

bool SpinLock_TryLock(int * lock)
{
int zero = 0;
return compare_exchange_strong(lock,&zero,1);
}
which returns false if it couldn't get the lock (and then might do an OS wait) - you don't want to return false just because of a spurious failure. (that's not a great example, maybe I'll think of a better one later).
(BTW I think the C++0x stuff is a little bit broken, like most of C standardization, because they are trying to straddle this middle ground of exposing the efficient hardware-specific ways of doing things, but they don't actually expose enough to map directly to the hardware, and they also aren't high level enough to separate you from knowing about the hardware. For example none of their memory model actually maps directly to what x86 provides, therefore there are some very efficient x86-specific ways to do threading ops that cannot be expressed portable in C++0x. Similarly on LL-SC architectures, it would be preferrable to just have access to LL-SC directly.

I'd rather see things in the standard like "if LL-SC exist on this architecture, then they can be invoked via __ll() and __sc()" ; more generally I wish C had more conditionals built into the language, that would be so much better for real portability, as opposed to the current mess where they pretend that the language is portable but it actually isn't so you have to create your own mess of meta-language through #defines).  回復(fù)  更多評論
  


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩午夜免费| 亚洲免费成人av| 亚洲激情av| 欧美性做爰毛片| 欧美精品观看| 久久中文字幕导航| 久久婷婷影院| 久久久久久精| 久久婷婷国产麻豆91天堂| 亚洲欧美99| 久久午夜精品一区二区| 老司机久久99久久精品播放免费 | 国产视频亚洲| 国产欧美日韩三区| 国内精品久久久久久| 一区二区三区中文在线观看 | 国产精品久久中文| 国产精品v亚洲精品v日韩精品| 欧美日韩国产高清| 亚洲高清不卡在线| 欧美国产日本在线| 国产日韩欧美日韩| 亚洲国产精品传媒在线观看| 亚洲国产精品悠悠久久琪琪| 加勒比av一区二区| aⅴ色国产欧美| 久久久青草青青国产亚洲免观| 免费国产自线拍一欧美视频| 91久久中文| 亚洲一区日本| 欧美电影免费观看高清| 国产视频在线观看一区二区三区| 在线观看日韩av先锋影音电影院| 一区二区三区日韩| 欧美+日本+国产+在线a∨观看| 一区二区三区国产| 欧美国产亚洲视频| 在线色欧美三级视频| 久久精品国产91精品亚洲| 亚洲欧洲中文日韩久久av乱码| 免费成人网www| 精品999日本| 久久亚洲捆绑美女| 国产区亚洲区欧美区| 亚洲一二三区视频在线观看| 欧美 日韩 国产一区二区在线视频| 国产精品视频久久| 欧美综合国产| 久久深夜福利| av不卡免费看| 一区二区三区视频免费在线观看| 欧美日韩国产在线一区| 亚洲午夜免费福利视频| 中文av一区特黄| 国产精品一区久久久久| 欧美α欧美αv大片| 一区二区日韩免费看| 亚洲综合国产| 亚洲国产老妈| 亚洲一区在线观看视频| 精品99一区二区| 99视频精品免费观看| 国产一区999| 亚洲精品社区| 激情欧美亚洲| 亚洲性图久久| 在线视频亚洲一区| 久久久噜噜噜久噜久久| 亚洲一区二区三区影院| 久久久久女教师免费一区| 亚洲视频欧美在线| 欧美电影免费观看高清| 麻豆精品视频在线| 国产日韩欧美日韩| 欧美亚洲一区二区在线| 亚洲免费网站| 欧美婷婷在线| 一本久久综合亚洲鲁鲁| 亚洲精品日韩激情在线电影| 久久国产视频网| 久久五月婷婷丁香社区| 国产亚洲毛片在线| 久久久91精品国产| 另类酷文…触手系列精品集v1小说| 欧美午夜电影完整版| 99综合在线| 久久精品女人天堂| 国产亚洲欧洲997久久综合| 亚洲少妇在线| 性欧美18~19sex高清播放| 国产精品日韩精品欧美在线| 亚洲——在线| 国产精品一区二区三区乱码| 性欧美大战久久久久久久免费观看 | 亚洲欧美中文字幕| 国产精品igao视频网网址不卡日韩| 日韩亚洲视频在线| 久久网站热最新地址| 亚洲精品欧美精品| 国产手机视频一区二区| 蜜臀久久久99精品久久久久久 | 久久免费少妇高潮久久精品99| 国产一区二区三区无遮挡| 男女精品网站| 欧美主播一区二区三区美女 久久精品人| 久久综合一区二区| 亚洲主播在线| 一区二区三区成人| 亚洲精品黄色| 在线免费观看欧美| 国产一区二区三区黄视频| 欧美精品99| 欧美精品九九99久久| 久久久久久亚洲精品中文字幕| 日韩视频一区二区三区在线播放免费观看 | 樱桃成人精品视频在线播放| 欧美国产视频在线观看| 久久九九久久九九| 久久成人精品无人区| 亚洲一区二区三区免费视频| 一本色道精品久久一区二区三区| 国产一二三精品| 国产精品久久久久三级| 欧美肉体xxxx裸体137大胆| 欧美激情一区二区三级高清视频| 欧美在线观看视频一区二区| 夜夜嗨av色一区二区不卡| 一区二区高清视频| 亚洲特级毛片| 久久天堂精品| 国产精品成人一区二区网站软件| 国产精品看片你懂得| 国产亚洲成av人在线观看导航| 国产亚洲精品美女| 亚洲人成网站在线观看播放| 日韩亚洲欧美高清| 亚洲欧美国产另类| 免费观看日韩| 亚洲婷婷在线| 欧美成va人片在线观看| 欧美午夜精品久久久久久超碰| 国产亚洲人成a一在线v站| 亚洲精品在线看| 久久精品首页| 中文精品在线| 欧美日韩亚洲网| 狠狠干成人综合网| 欧美一二区视频| 影音先锋久久资源网| 在线免费高清一区二区三区| 亚洲精品偷拍| 久久久国产一区二区三区| 99精品热6080yy久久| 欧美成人国产一区二区| 国内精品久久久久久久97牛牛| 亚洲午夜视频| 一区二区三区欧美激情| 欧美日韩国产成人精品| 91久久久在线| 欧美成人午夜激情| 男男成人高潮片免费网站| 亚洲国产一区二区三区在线播| 久久九九全国免费精品观看| 欧美在线视频不卡| 亚洲中无吗在线| 国产美女精品| 欧美电影在线免费观看网站| 久久亚洲欧美| 亚洲最黄网站| 一本一本久久a久久精品综合妖精| 欧美伦理在线观看| 亚洲自拍三区| 久久久福利视频| 一二三区精品福利视频| 亚洲男人天堂2024| 亚洲国产一区二区视频| 亚洲天堂成人在线视频| 91久久国产自产拍夜夜嗨| 亚洲视频在线视频| 99精品国产一区二区青青牛奶| 亚洲一区三区在线观看| 亚洲人成77777在线观看网| 亚洲在线视频免费观看| 亚洲一区二区黄色| 欧美大尺度在线观看| 老司机免费视频一区二区| 国产精品家庭影院| 日韩午夜免费| 亚洲男人第一网站| 欧美激情中文字幕一区二区| 免费观看一级特黄欧美大片| 国产日韩亚洲欧美| 宅男噜噜噜66一区二区66| 9i看片成人免费高清| 欧美丰满少妇xxxbbb| 欧美激情精品久久久久久变态| 黑丝一区二区三区| 久久久久久久久岛国免费| 久久久亚洲人| 亚洲国产精品精华液2区45|