• <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>
            posts - 200, comments - 8, trackbacks - 0, articles - 0
            當(dāng)使用讀/寫自旋鎖時(shí),內(nèi)核控制路徑發(fā)出的執(zhí)行read_lock或write_lock操作的請(qǐng)求具有相同的優(yōu)先權(quán):讀者必須等待,直到寫操作完成。同樣地,寫者也必須等待,直到讀操作完成。

            Linux 2.6中引入了順序鎖(seqlock),它與讀/寫自旋鎖非常相似,只是它為寫者賦予了較高的優(yōu)先級(jí):事實(shí)上,即使在讀者正在讀的時(shí)候也允許寫者繼續(xù)運(yùn)行。這種策略的好處是寫者永遠(yuǎn)不會(huì)等待讀(除非另外一個(gè)寫者正在寫),缺點(diǎn)是有些時(shí)候讀者不得不反復(fù)讀多次相同的數(shù)據(jù)直到它獲得有效的結(jié)果。

            每個(gè)順序鎖都是包括兩個(gè)字段的seqlock_t結(jié)構(gòu):
            typedef struct {
                unsigned sequence;
                spinlock_t lock;
            } seqlock_t;

            一個(gè)類型為spinlock_t的lock字段和一個(gè)整型的sequence字段,第二個(gè)字段sequence是一個(gè)順序計(jì)數(shù)器。

            每個(gè)讀者都必須在讀數(shù)據(jù)前后兩次讀順序計(jì)數(shù)器,并檢查兩次讀到的值是否相同,如果不相同,說明新的寫者已經(jīng)開始寫并增加了順序計(jì)數(shù)器,因此暗示讀者剛讀到的數(shù)據(jù)是無效的。

            通過把SEQLOCK_UNLOCKED賦給變量seqlock_t或執(zhí)行seqlock_init宏,把seqlock_t變量初始化為“未上鎖”,并把sequence設(shè)為0:
            #define __SEQLOCK_UNLOCKED(lockname) /
                     { 0, __SPIN_LOCK_UNLOCKED(lockname) }

            #define SEQLOCK_UNLOCKED /
                     __SEQLOCK_UNLOCKED(old_style_seqlock_init)

            # define __SPIN_LOCK_UNLOCKED(lockname) /
                (spinlock_t)    {    .raw_lock = __RAW_SPIN_LOCK_UNLOCKED,    /
                            SPIN_DEP_MAP_INIT(lockname) }
            #define __RAW_SPIN_LOCK_UNLOCKED    { 1 }

            寫者通過調(diào)用write_seqlock()和write_sequnlock()獲取和釋放順序鎖。write_seqlock()函數(shù)獲取seqlock_t數(shù)據(jù)結(jié)構(gòu)中的自旋鎖,然后使順序計(jì)數(shù)器sequence加1;write_sequnlock()函數(shù)再次增加順序計(jì)數(shù)器sequence,然后釋放自旋鎖。這樣可以保證寫者在整個(gè)寫的過程中,計(jì)數(shù)器sequence的值是奇數(shù),并且當(dāng)沒有寫者在改變數(shù)據(jù)的時(shí)候,計(jì)數(shù)器的值是偶數(shù)。讀者進(jìn)程執(zhí)行下面的臨界區(qū)代碼:

                unsigned int seq;
                do {
                    seq = read_seqbegin(&seqlock);
                    /* ... CRITICAL REGION ... */
                } while (read_seqretry(&seqlock, seq));

            read_seqbegin()返回順序鎖的當(dāng)前順序號(hào);如果局部變量seq的值是奇數(shù)(寫者在read_seqbegin()函數(shù)被調(diào)用后,正更新數(shù)據(jù)結(jié)構(gòu)),或seq的值與順序鎖的順序計(jì)數(shù)器的當(dāng)前值不匹配(當(dāng)讀者正執(zhí)行臨界區(qū)代碼時(shí),寫者開始工作),read_seqretry()就返回1:
            static __always_inline int read_seqretry(const seqlock_t *sl, unsigned iv)
            {
                smp_rmb();
                return (iv & 1) | (sl->sequence ^ iv);
            }


            注意在順序鎖機(jī)制里,讀者可能反復(fù)讀多次相同的數(shù)據(jù)直到它獲得有效的結(jié)果(read_seqretry返回0)。另外,當(dāng)讀者進(jìn)入臨界區(qū)時(shí),不必禁用內(nèi)核搶占;另一方面,由寫者獲取自旋鎖,所以它進(jìn)入臨界區(qū)時(shí)自動(dòng)禁用內(nèi)核搶占。

            并不是每一種資源都可以使用順序鎖來保護(hù)。一般來說,必須在滿足下述條件時(shí)才能使用順序鎖:

            (1)被保護(hù)的數(shù)據(jù)結(jié)構(gòu)不包括被寫者修改和被讀者間接引用 的指針(否則,寫者可能在讀者的眼皮子底下就修改指針)。
            (2)讀者的臨界區(qū)代碼沒有副作用(否則,多個(gè)讀者的操作會(huì)與單獨(dú)的讀操作有不同的結(jié)果)。

            此外,讀者的臨界區(qū)代碼應(yīng)該簡(jiǎn)短,而且寫者應(yīng)該不常獲取順序鎖,否則,反復(fù)的讀訪問會(huì)引起嚴(yán)重的開銷。在Linux 2.6中,使用順序鎖主要是保護(hù)一些與系統(tǒng)時(shí)間處理相關(guān)的數(shù)據(jù)結(jié)構(gòu)。 
            日本欧美国产精品第一页久久| 狠狠色狠狠色综合久久 | 国产三级观看久久| 久久夜色撩人精品国产小说| 色婷婷久久综合中文久久蜜桃av| 91精品婷婷国产综合久久| 日韩欧美亚洲综合久久影院Ds| 久久大香萑太香蕉av| 欧美亚洲国产精品久久蜜芽| 久久久久青草线蕉综合超碰| 免费一级做a爰片久久毛片潮 | 久久精品一区二区三区中文字幕| 女人香蕉久久**毛片精品| 欧美与黑人午夜性猛交久久久| 亚洲精品高清国产一线久久| 欧美粉嫩小泬久久久久久久 | 99国产欧美精品久久久蜜芽 | 99久久国产综合精品女同图片| 久久精品国产亚洲欧美| 91精品国产高清91久久久久久| 久久无码国产| 久久se这里只有精品| 99久久亚洲综合精品成人| 亚洲精品无码成人片久久| 日本精品久久久中文字幕| 伊人久久综合精品无码AV专区| 99久久综合国产精品免费| 国产精品久久久久国产A级| 一级做a爰片久久毛片毛片| 久久狠狠一本精品综合网| 精品人妻久久久久久888| 无码国内精品久久人妻蜜桃| 久久久久波多野结衣高潮| 欧美久久久久久精选9999| 久久黄视频| 性高湖久久久久久久久AAAAA| 久久久精品久久久久久| 久久婷婷五月综合色99啪ak| 久久国产亚洲精品| 久久丫精品国产亚洲av不卡| 国产99久久久国产精品小说|