• <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
            當使用讀/寫自旋鎖時,內核控制路徑發出的執行read_lock或write_lock操作的請求具有相同的優先權:讀者必須等待,直到寫操作完成。同樣地,寫者也必須等待,直到讀操作完成。

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

            每個順序鎖都是包括兩個字段的seqlock_t結構:
            typedef struct {
                unsigned sequence;
                spinlock_t lock;
            } seqlock_t;

            一個類型為spinlock_t的lock字段和一個整型的sequence字段,第二個字段sequence是一個順序計數器。

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

            通過把SEQLOCK_UNLOCKED賦給變量seqlock_t或執行seqlock_init宏,把seqlock_t變量初始化為“未上鎖”,并把sequence設為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 }

            寫者通過調用write_seqlock()和write_sequnlock()獲取和釋放順序鎖。write_seqlock()函數獲取seqlock_t數據結構中的自旋鎖,然后使順序計數器sequence加1;write_sequnlock()函數再次增加順序計數器sequence,然后釋放自旋鎖。這樣可以保證寫者在整個寫的過程中,計數器sequence的值是奇數,并且當沒有寫者在改變數據的時候,計數器的值是偶數。讀者進程執行下面的臨界區代碼:

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

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


            注意在順序鎖機制里,讀者可能反復讀多次相同的數據直到它獲得有效的結果(read_seqretry返回0)。另外,當讀者進入臨界區時,不必禁用內核搶占;另一方面,由寫者獲取自旋鎖,所以它進入臨界區時自動禁用內核搶占。

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

            (1)被保護的數據結構不包括被寫者修改和被讀者間接引用 的指針(否則,寫者可能在讀者的眼皮子底下就修改指針)。
            (2)讀者的臨界區代碼沒有副作用(否則,多個讀者的操作會與單獨的讀操作有不同的結果)。

            此外,讀者的臨界區代碼應該簡短,而且寫者應該不常獲取順序鎖,否則,反復的讀訪問會引起嚴重的開銷。在Linux 2.6中,使用順序鎖主要是保護一些與系統時間處理相關的數據結構。 
            久久久久久免费一区二区三区| 久久亚洲国产成人精品性色| 亚洲狠狠综合久久| 99久久99久久精品国产| 久久精品无码一区二区三区日韩| 亚洲国产成人精品无码久久久久久综合 | 亚洲国产精品综合久久网络| 久久人人爽人人爽人人片AV高清| 久久精品水蜜桃av综合天堂| 久久久久国产一区二区| 99精品久久久久中文字幕| 老男人久久青草av高清| 99久久亚洲综合精品网站| 亚洲av日韩精品久久久久久a| 97久久精品人人做人人爽| 久久精品国产99久久无毒不卡| 久久亚洲精品无码观看不卡| 久久99亚洲网美利坚合众国| 狠狠色丁香久久婷婷综合_中| 久久美女人爽女人爽| 亚洲AV无码成人网站久久精品大| 亚洲午夜久久久| 热RE99久久精品国产66热| 久久se精品一区二区| 成人国内精品久久久久一区| 久久精品国产99国产精品亚洲 | 欧美一区二区精品久久| 性色欲网站人妻丰满中文久久不卡| 欧洲性大片xxxxx久久久| 99久久精品免费看国产免费| 国产精品久久国产精品99盘| 久久精品国产亚洲av影院| 精品久久久噜噜噜久久久| 久久久噜噜噜久久中文福利| 久久婷婷国产综合精品| 无码人妻久久一区二区三区| 亚洲AV无码久久精品蜜桃| 久久丫精品国产亚洲av不卡 | 亚洲色大成网站WWW久久九九| 久久青青草视频| 久久亚洲AV成人出白浆无码国产|