日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > 互聯(lián)網(wǎng) > 《Linux Device Drivers》第五章 并發(fā)和競態(tài)――note

《Linux Device Drivers》第五章 并發(fā)和競態(tài)――note

來源:程序員人生   發(fā)布時間:2014-10-03 08:00:01 閱讀次數(shù):2774次
  • 并發(fā)及其管理
    • 競態(tài)通常作為對資源的共享訪問結(jié)果而產(chǎn)生
    • 當兩個執(zhí)行線程需要訪問相同的數(shù)據(jù)結(jié)構(gòu)(或硬件資源)時,并發(fā)的可能性就永遠存在
    • 只要可能就應該避免資源的共享,但共享通常是必須的,硬件本質(zhì)上就是共享的
    • 訪問管理的常見技術(shù)稱為“鎖定”或者“互斥”
  • 信號量和互斥體
    • 建立臨界區(qū):在任意給定的時刻,代碼只能被一個線程執(zhí)行
    • 可以使用一種鎖定機制,當進程在等待對臨界區(qū)的訪問時,此機制可讓進程進入休眠狀態(tài)
    • 一個信號量本質(zhì)上是一個整數(shù)值,它和一對函數(shù)聯(lián)合使用,這一對函數(shù)通常稱為P和V
    • 當信號量用于互斥時,信號量的值應初始化為1,這種信號量有時也稱為“互斥體(mutex)”
    • Linux信號量的實現(xiàn)
      • <asm/semaphore.h>
      • struct semaphore;
      • void sema_init(struct semaphore *sem, int val);
      • DECLARE_MUTEX(name);
        • 稱為name的信號量變量被初始化為1
      • DECLARE_MUTEX_LOCKED(name);
        • 稱為name的信號量變量被初始化為0
      • void init_MUTEX(struct semaphore *sem);
      • void init_MUTEX_LOCKED(struct semaphore *sem);
      • void down(struct semaphore *sem);
        • 一直等待
      • int down_interruptible(struct semaphore *sem);
        • 操作是可中斷的
        • 如果操作被中斷,該函數(shù)會返回非零值
        • 通常使用的是可中斷的down版本
      • int down_trylock(struct semaphore *sem);
        • 永遠不會休眠
        • 如果信號量在調(diào)用時不可獲得,會立即返回一個非零值
      • void up(struct semaphore *sem);
    • 讀取者/寫入者信號量
      • 一些任務只需要讀取受保護的數(shù)據(jù)結(jié)構(gòu),而其他的則必須做出修改
      • <linux/rwsem.h>
      • struct rw_semaphore;
      • void init_rwsem(struct rw_semaphore *sem);
      • void down_read(struct rw_semaphore *sem);
        • 只讀訪問,可和其他讀取者并發(fā)地訪問
      • int down_read_trylock(struct rw_semaphore *sem);
        • 在授予訪問時返回非零,其他情況下返回零
      • void up_read(struct rw_semaphore *sem);
      • void down_write(struct rw_semaphore *sem);
      • int down_write_trylock(struct rw_semaphore *sem);
      • void up_write(struct rw_semaphore *sem);
      • void downgrade_write(struct rw_semaphore *sem);
      • 最好在很少需要寫訪問且寫入者只會短期擁有信號量的時候使用rwsem

  • completion
    • 內(nèi)核編程中常見的一種模式是,在當前線程之外初始化某個活動,然后等待該活動的結(jié)束
    • <linux/completion.h>
    • DECLARE_COMPLETION(my_completion);
    • init_completion(struct completion *c);
    • void wait_for_completion(struct completion *c);
      • 非中斷的等待
    • void complete(struct completion *c);
    • void complete_all(struct completion *c);
    • 一個completion通常是一個單次(one-shot)設備
    • 如果沒有使用complete_all,可以重復使用一個complete結(jié)構(gòu)
    • 如果使用了complete_all,則必須在重復使用該結(jié)構(gòu)之前重新初始化它
    • INIT_COMPLETE(struct completion c);
    • void complete_and_exit(struct completion *c, long retval);
  • 自旋鎖
    • 自旋鎖可在不能休眠的代碼中使用,比如中斷處理例程
    • 可提供比信號量更高的性能
    • 一個自旋鎖是一個互斥設備,它只能有兩個值:鎖定和解鎖
    • 通常實現(xiàn)為某個整數(shù)值中的單個位
    • 如果鎖可用,則“鎖定”位被設置,而代碼繼續(xù)進入臨界區(qū)
    • 如果鎖被其他人獲得,則代碼進入忙循環(huán)并重復檢查這個鎖,直到該鎖可用為止,這個循環(huán)就是自旋鎖的“自旋”部分
    • “測試并設置”的操作必須以原子方式完成
    • 在超線程處理器上,還必須仔細處理以避免死鎖,超線程處理器可實現(xiàn)多個虛擬的CPU,它們共享單個處理器核心及緩存
    • 自旋鎖API介紹
      • <linux/spinlock.h>
      • spinlock_t
      • spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
      • void spin_lock_init(spinlock_t *lock);
      • void spin_lock(spinlock_t *lock);
        • 不可中斷
        • 在獲得鎖之前一直處于自旋狀態(tài)
      • void spin_unlock(spinlock_t *lock);
    • 自旋鎖和原子上下文
      • 任何擁有自旋鎖的代碼都必須是原子的,不能休眠,不能因為任何原因放棄處理器,除了服務中斷之外
    • 自旋鎖函數(shù)
      • void spin_lock(spinlock_t *lock);
      • void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
        • 在獲得自旋鎖之前禁止中斷,而先前的中斷狀態(tài)保存在flags中
      • void spin_lock_irq(spinlock_t *lock);
      • void spin_lock_bh(spinlock_t *lock);
        • 在獲得鎖之前禁止軟件中斷
      • void spin_unlock(spinlock_t *lock);
      • void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
        • flags參數(shù)必須是傳遞給spin_lock_irqsave的同一個變量
      • void spin_unlock_irq(spinlock_t *lock);
      • void spin_unlock_bh(spinlock_t *lock);
      • int spin_trylock(spinlock_t *lock);
        • 成功時返回非零值,否則返回零
      • int spin_trylock_bh(spinlock_t *lock);
        • 成功時返回非零值,否則返回零
    • 讀取值/寫入者自旋鎖
      • <linux/spinlock.h>
      • rwlock_t
      • rwlock_t my_rwlock = RW_LOCK_UNLOCKED;
      • void rwlock_init(rwlock_t * lock);
      • void read_lock(rwlock_t *lock);
      • void read_lock_irqsave(rwlock_t *lock, unsigned long flags);
      • void read_lock_irq(rwlock_t *lock);
      • void read_lock_bh(rwlock_t *lock);
      • void read_unlock(rwlock_t *lock);
      • void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
      • void read_unlock_irq(rwlock_t *lock);
      • void read_unlock_bh(rwlock_t *lock);
      • void write_lock(rwlock_t *lock);
      • void write_lock_irqsave(rwlock_t *lock, unsigned long flags);
      • void write_lock_irq(rwlock_t *lock);
      • void write_lock_bh(rwlock_t *lock);
      • int write_trylock(rwlock_t *lock);
      • void write_unlock(rwlock_t *lock);
      • void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
      • void write_unlock_irq(rwlock_t *lock);
      • void write_unlock_bh(rwlock_t *lock);
      • 讀取者/寫入者鎖可能造成讀取者饑餓
  • 鎖陷阱
    • 不明確的規(guī)則
      • 不論是信號量還是自旋鎖,都不允許鎖擁有者第二次獲得這個相同的鎖,如果試圖這樣做,系統(tǒng)將掛起
    • 鎖的順序規(guī)則
      • 在必須獲取多個鎖時,應該始終以相同的順序獲得
      • 如果必須獲得一個局部鎖以及一個屬于內(nèi)核更中心位置的鎖,則應該首先獲取自己的局部鎖
      • 如果擁有信號量和自旋鎖的組合,則必須首先獲得信號量
    • 細粒度鎖和粗粒度鎖的對比
      • 細粒度鎖具有良好的伸縮性
      • 細粒度鎖將帶來某種程序的復雜性
      • 應該在最初使用粗粒度的鎖
      • 使用lockmeter工具可度量內(nèi)核花費在鎖上的時間
        • http://oss.sgi.com/projects/lockmeter/
  • 除了鎖之外的方法
    • 免鎖算法
      • 經(jīng)常用于免鎖的生產(chǎn)者/消費者任務的數(shù)據(jù)結(jié)構(gòu)之一是循環(huán)緩沖區(qū)
    • 原子變量
      • <asm/atomic.h>
      • atomic_t
      • 一個atomic_t變量保存一個int值,但不能記錄大于24位的整數(shù)
      • void atomic_set(atomic_t *v, int i);
      • atomic_t v = ATOMIC_INIT(0);
      • int atomic_read(atomic_t *v);
      • void atomic_add(int i, atomic_t *v);
      • void atomic_sub(int i, atomic_t *v);
      • void atomic_inc(atomic_t *v);
      • void atomic_dec(atomic_t *v);
      • int atomic_inc_and_test(atomic_t *v);
      • int atomic_dec_and_test(atomic_t *v);
      • int atomic_sub_and_test(int i, atomic_t *v);
      • int atomic_add_negative(int i, atomic_t *v);
      • int atomic_add_return(int i, atomic_t *v);
      • int atomic_sub_return(int i, atomic_t *v);
      • int atomic_inc_return(atomic_t *v);
      • int atomic_dec_return(atomic_t *v);
      • 需要多個atomic_t變量的操作,仍然需要某種類型的鎖
    • 位操作
      • <asm/bitops.h>
      • nr參數(shù)通常被定義為int,但在少數(shù)架構(gòu)上被定義為unsigned long
      • void set_bit(nr, void *addr);
      • void clear_bit(nr, void *addr);
      • void change_bit(nr, void *addr);
      • test_bit(nr, void *addr);
      • int test_and_set_bit(nr, void *addr);
      • int test_add_clear_bit(nr, void *addr);
      • int test_and_change_bit(nr, void *addr);
    • seqlock
      • 允許讀取者對資源的自由訪問,但需要讀取者檢查是否和寫入者發(fā)生沖突
      • <linux/seqlock.h>
      • seqlock_t
      • seqlock_t lock1 = SEQLOCK_UNLOCKED;
      • void seqlock_init(seqlock_t *lock);
      • unsigned int read_seqbegin(seqlock_t *lock);
      • int read_seqretry(seqlock_t *lock, unsigned int seq);
      • unsigned int read_seqbegin_irqsave(seqlock_t *lock, unsigned long flags);
      • int read_seqretry_irqrestore(seqlock_t *lock, unsigned int seq, unsigned long flags);
      • void write_seqlock(seqlock_t *lock);
      • void write_sequnlock(seqlock_t *lock);
      • void write_seqlock_irqsave(seqlock_t *lock, unsigned long flags);
      • void write_seqlock_irq(seqlock_t *lock);
      • void write_seqlock_bh(seqlock_t *lock);
      • void write_sequnlock_irqrestore(seqlock_t *lock, unsigned long flags);
      • void write_sequnlock_irq(seqlock_t *lock);
      • void write_sequnlock_bh(seqlock_t *lock);
    • 讀取-復制-更新
      • read-copy-update(RCU)也是一種高級的互斥機制
      • 很少在驅(qū)動程序中使用
      • http://www.rdrop.com/users/paulmck/rclock/intro/rclock_intro.html
      • 針對經(jīng)常發(fā)生讀取而很少寫入的情形做了優(yōu)化
      • 被保護的資源應該通過指針訪問
      • 在需要修改該數(shù)據(jù)結(jié)構(gòu)時,寫入線程首先復制,然后修改副本,之后用新的版本替代相關(guān)指針。當確信老的版本沒有其他引用時,就可釋放老的版本
      • <linux/rcupdate.h>
      • rcu_read_lock
      • rcu_read_unlock
      • void call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg);
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产一区精品在线 | 亚洲成人毛片 | 欧美色88| 日韩精品久久久 | 在线视频 中文字幕 | 成人欧美一区二区 | 九九热在线视频 | 亚洲欧美在线观看 | www.av视频在线观看 | 成人在线黄色 | av资源网在线观看 | 波多野结衣国产 | 国产一区视频在线 | 久久aⅴ乱码一区二区三区 精品99久久久久久 99热视 | 天堂网2018| 国内av免费 | 欧美一区 | 国产视频a | 国产精品成人一区 | 国内精品久久久久影院薰衣草 | 日韩av网站在线 | 免费不卡视频 | 午夜视频污 | 成人在线国产 | 午夜视频网 | 精品欧美一区二区三区在线观看 | 国产三级在线看 | 午夜精品国产精品大乳美女 | 操女人在线 | 在线播放日韩 | 97久久超碰国产精品电影 | 成人福利 | 久久久三级 | 欧美少妇一级片 | 久久99精品国产一区二区三区 | 蜜桃精品一区二区三区 | 欧美日韩福利视频 | 国产4区| 国产精品三级在线 | 国产精品一区二区三区四区五区 | 亚州男人天堂 |