嵌入式系統(tǒng)設(shè)計(jì)-第08講-并發(fā)與競(jìng)態(tài)_第1頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)-第08講-并發(fā)與競(jìng)態(tài)_第2頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)-第08講-并發(fā)與競(jìng)態(tài)_第3頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)-第08講-并發(fā)與競(jìng)態(tài)_第4頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)-第08講-并發(fā)與競(jìng)態(tài)_第5頁(yè)
已閱讀5頁(yè),還剩41頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

本節(jié)內(nèi)容并發(fā)和競(jìng)態(tài)中斷信號(hào)量和互斥體Completion自旋鎖原子操作SeqlockRCU(Read-Copy-Update)2020/11/122中斷并發(fā)和競(jìng)態(tài)控制信號(hào)量和互斥體completion自旋鎖原子操作seqlockRCU(Read-Copy-Update)并發(fā)和競(jìng)態(tài)西安電子科技大學(xué)學(xué)院3并發(fā)和競(jìng)態(tài)并發(fā)?多個(gè)執(zhí)行單元同時(shí)、并行被執(zhí)行。競(jìng)態(tài)(raceconditions)并發(fā)的執(zhí)行單元對(duì)共享資源的

則很容易導(dǎo)致。共享資源:–

硬件資源,

上的全局變量、靜態(tài)變量等Linux內(nèi)核中,什么情況會(huì)發(fā)生競(jìng)態(tài)?對(duì)稱(chēng)多處理器(SMP)的多個(gè)CPU單CPU內(nèi)進(jìn)程與搶占它的進(jìn)程中斷(硬中斷、軟中斷、Tasklet、底半部)與進(jìn)程之間并發(fā)和競(jìng)態(tài)如何解決競(jìng)態(tài)問(wèn)題?保證對(duì)共享資源的互斥

,指一個(gè)執(zhí)行單元在

共享資源的時(shí)候,其他的執(zhí)行單元被

。Linux設(shè)備驅(qū)動(dòng)中可采用的互斥途徑中斷原子操作自旋鎖信號(hào)量completion中斷西安電子科技大學(xué)學(xué)院6中斷中斷

:可解決中斷與進(jìn)程之間的并發(fā);也可解決內(nèi)核搶占進(jìn)程之間的并發(fā)主要函數(shù)注意:不要長(zhǎng)時(shí)間中斷,由于Linux系統(tǒng)的異步I/O、進(jìn)程調(diào)度等很多重要操作都依賴(lài)于中斷,在中斷期間所有的中斷都無(wú)法得到處理,因此長(zhǎng)時(shí)間的,有可能造成數(shù)據(jù)丟失甚至系統(tǒng)中斷是很。中斷l(xiāng)ocal_irq_disable()//…critical

section//臨界區(qū)…local_irq_enable()//打開(kāi)中斷信號(hào)量和互斥體西安電子科技大學(xué)學(xué)院8信號(hào)量和互斥體信號(hào)量(

semaphore

)信號(hào)量本質(zhì)上是一個(gè)整數(shù)值,一對(duì)操作函數(shù)通常稱(chēng)為P和V。進(jìn)入臨界區(qū)相關(guān)信號(hào)量上調(diào)用P;如果信號(hào)量>零,則該值會(huì)減小一,而進(jìn)程可以繼續(xù)。如果信號(hào)量的值=零(或更小),進(jìn)程必須等待直到其他人信號(hào)量。退出臨界區(qū)該信號(hào)量的

通過(guò)調(diào)用V完成;該函數(shù)增加信號(hào)量的值,并在必要時(shí)喚醒等待的進(jìn)程。信號(hào)量和互斥體當(dāng)信號(hào)量用于互斥避免多個(gè)進(jìn)程同時(shí)在一個(gè)臨界區(qū)中運(yùn)行信號(hào)量的值應(yīng)初始化為1。只能由單個(gè)進(jìn)程或線(xiàn)程擁有。一個(gè)信號(hào)量有時(shí)也稱(chēng)為一個(gè)“互斥體(mutex)”,它是互斥(mutual

exclusion)的簡(jiǎn)稱(chēng)。Linux內(nèi)核中幾乎所有的信號(hào)量均用于互斥。信號(hào)量和互斥體初始化信號(hào)量信號(hào)量類(lèi)型為struct

semaphore;信號(hào)量可通過(guò)幾種途徑來(lái) 和初始化:動(dòng)態(tài)的初始化信號(hào)量#include

<asm/semaphore.h>void

sema_init(struct

semaphore

*sem,int

val);信號(hào)量的初始值靜態(tài)的 互斥信號(hào)量:DECLARE_MUTEX(name);DECLARE_MUTEX_LOCKED(name);互斥信號(hào)量“name”,并初始化為1動(dòng)態(tài)的初始化互斥信號(hào)量:void

init_MUTEX(struct

semaphore

*sem);void

init_MUTEX_LOCKED(struct

semaphore

*sem);信號(hào)量和互斥體獲得信號(hào)量信號(hào)量void

down(struct

semaphore

*sem);int

down_interruptible(struct

semaphore

*sem);int

down_trylock(struct

semaphore

*sem);減小信號(hào)量的值,如果不能獲得信號(hào)量就一直等待完成和down相同的工作,但操作是可中斷的不會(huì)休眠,如果信號(hào)量在調(diào)用時(shí)不可獲得,就會(huì)立即返回一個(gè)非零值。void

up(struct

semaphore

*sem);信號(hào)量和互斥體使用信號(hào)量模板DECLARE_MUTEX(sem);if(down_interruptible(&sem)){return

–ERESTARTSYS;}…critical

section…up(&sem);定義信號(hào)量獲取信號(hào)量,保護(hù)臨界區(qū)臨界區(qū)信號(hào)量讀寫(xiě)信號(hào)量者/寫(xiě)入者信號(hào)量數(shù)據(jù)類(lèi)型:structrw_semaphore;初始化:void

init_rwsem(structrw_semaphore

*sem);主要函數(shù):void

down_read(struct

rw_semaphore

*sem);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);讀寫(xiě)信號(hào)量者/寫(xiě)入者信號(hào)量實(shí)例rw_semaphore_t

rw_sem;init_rwsem(&rw_sem);//讀時(shí)獲取信號(hào)量down_read(&rw_sem);…//臨界資源up_read(&rw_sem);down_write(&rw_sem);…//臨界資源up_write(&rw_sem);定義讀寫(xiě)信號(hào)量初始化讀寫(xiě)信號(hào)量獲取臨界資源臨界區(qū)臨界資源completion西安電子科技大學(xué)學(xué)院16completion一種輕量級(jí)的機(jī)制它允許一個(gè)線(xiàn)程告訴另一線(xiàn)程某個(gè)工作已經(jīng)完成。初始化等待completion#include

<pletion.h>PLETION(pletion);struct

completionpletion(pletion;pletion);/*

kernel/sched.c

*/voidpletion(struct

completion

*c);completion觸發(fā)完成/*

kernel/sched.c

*/void

complete(struct

completion*c);void

complete_all(struct

completion*c);必須在重復(fù)使用該結(jié)構(gòu)之前重新初始化它。下面這個(gè)宏可用來(lái)快速執(zhí)行重新初始化:PLETION(struct

completion

c);completioncompletion使用示例PLETION(

p);ssize_t

complete_read(struct

file*filp,char

user

*buf,size_t

count,loff_t

*pos){pletion(

p);return

0;}ssize_tcomplete_write(structfile*filp,constchar

user

*buf,size_t

count,loff_t

*pos){complete(

p);return

count;}定義并初始化completion等待某個(gè)事件完成表示某個(gè)事件完成自旋鎖西安電子科技大學(xué)學(xué)院20自旋鎖概念一個(gè)自旋鎖是一個(gè)互斥設(shè)備,只有兩個(gè)值:“鎖定”和“”。實(shí)現(xiàn)為某個(gè)整數(shù)值中的單個(gè)位。希望獲得某特定鎖的代碼測(cè)試相關(guān)的位。鎖可用,則“鎖定”位被設(shè)置,而代碼繼續(xù)進(jìn)入臨界區(qū)如果鎖被其他人獲得,則代碼進(jìn)入忙循環(huán)并重復(fù)檢查這個(gè)鎖,直到該鎖可用為止。這個(gè)循環(huán)就是自旋鎖的“自旋”初始化自旋鎖#include<linux/spinlock.h>spinlock_t

_lock=SPIN_LOCK_UNLOCKED;void

spin_lock_init(spinlock_t

*lock);自旋鎖鎖定函數(shù)void

spin_lock(spinlock_t

*lock);void

spin_lock_irqsave(spinlock_t

*lock,unsigned

long

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);void

spin_unlock_irq(spinlock_t

*lock);void

spin_unlock_bh(spinlock_t

*lock);自旋鎖自旋鎖使用實(shí)例spinlock_t

lock;spin_lock_init(&lock);spin_lock(&lock);critical

sectionspin_unlock(&lock);定義一個(gè)自旋鎖初始化自旋鎖獲取自旋鎖,保護(hù)臨界區(qū)臨界區(qū)自旋鎖自旋鎖讀寫(xiě)自旋鎖任意數(shù)量的

者可以同時(shí)進(jìn)入臨界區(qū)寫(xiě)入者必須互斥變量類(lèi)型:rwlock_t初始化#include

<linux/spinlock.h>rwlock_t _rwlock

=RW_LOCK_UNLOCKED;rwlock_t

_rwlock;rwlock_init(&

_rwlock);自旋鎖者獲得鎖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

readunlock(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);自旋鎖寫(xiě)入者獲得鎖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);寫(xiě)入者

鎖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);自旋鎖讀寫(xiě)自旋鎖實(shí)例unsigned

long

flags;rwlock_t

rwlock;rwlock_init(&rwlock);read_lock(&rwlock);…//臨界資源read_unlock(&rwlock);//寫(xiě)時(shí)獲取鎖write_lock_irqsave(&rwlock,flags);…//臨界資源write_unlock_irqrestore(&rwlock,flags);定義rwlock初始化rwlock獲取鎖臨界區(qū)鎖自旋鎖自旋鎖VS信號(hào)量開(kāi)銷(xiāo)成本使用信號(hào)量的開(kāi)銷(xiāo)是進(jìn)程上下文切換時(shí)間自旋鎖的開(kāi)銷(xiāo)是忙等待獲取自旋鎖等待機(jī)制不同信號(hào)量可能導(dǎo)致阻塞,所以在不允許阻塞的代碼中不能用可能引起阻塞的信號(hào)量處理方式自旋鎖是忙等待比如,中斷處理程序自旋鎖避免死鎖規(guī)則自旋鎖的使用規(guī)則任何擁有自旋鎖的代碼都必須是原子的;如果中斷處理函數(shù)中也要獲得自選鎖,那么驅(qū)動(dòng)程序需要在擁有自旋鎖時(shí) 中斷;自旋鎖必須在可能的最短時(shí)間內(nèi)擁有;自旋鎖避免死鎖規(guī)則其他規(guī)則避免某個(gè)獲得鎖的函數(shù)調(diào)用其他同樣試圖獲取這個(gè)鎖的函數(shù),否則代碼就會(huì)死鎖;不論是信號(hào)量還是自旋鎖,都不允許鎖擁有者第二次獲得這個(gè)鎖,如果試圖這么做,系統(tǒng)將掛起;自旋鎖避免死鎖規(guī)則鎖的順序規(guī)則按同樣的順序獲得鎖如果必須獲得一個(gè)局部鎖和一個(gè)屬于內(nèi)核更中心位置的鎖,則應(yīng)該首先獲取自己的局部鎖如果

擁有信號(hào)量和自旋鎖的組合,則必須首先獲得信號(hào)量;在擁有自旋鎖時(shí)調(diào)用down(可導(dǎo)致休眠)是個(gè)嚴(yán)重的錯(cuò)誤的原子操作西安電子科技大學(xué)學(xué)院32原子操作原子變量加/減原子變量自增/自減整型原子操作類(lèi)型:atomic_t

(#include<asm/atomic.h>)void

atomic_set(atomic_t

*v,int

i);atomic_tv

=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);原子操作操作并測(cè)試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_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);原子操作位原子操作void

set_bit(nr,

void

*addr);void

clear_bit(nr,

void*addr);void

change_bit(nr,

void*addr);void

test_bit(nr,void

*addr);int

test_and_set_bit(nr,

void

*addr);int

test_and_clear_bit(nr,void*addr);int

test_and_change_bit(nr,

void

*addr)檢測(cè),并返回先前的值進(jìn)行對(duì)應(yīng)的操作設(shè)置第nr個(gè)bit的值清除第nr個(gè)bit的值改變第nr個(gè)bit的值檢測(cè)第nr

bit是否被設(shè)置Seqlock西安電子科技大學(xué)學(xué)院36Seqlock順序鎖(seqlock)是對(duì)讀寫(xiě)鎖的一種優(yōu)化,提高了讀鎖和寫(xiě)鎖的獨(dú)立性。寫(xiě)鎖不會(huì)被讀鎖阻塞,讀鎖也不會(huì)被寫(xiě)鎖阻塞。寫(xiě)鎖會(huì)被寫(xiě)鎖阻塞。用于能夠區(qū)分讀與寫(xiě)的場(chǎng)合,并且是讀操作很多、寫(xiě)操作很少,寫(xiě)操作的優(yōu)先權(quán)大于讀操作。被保護(hù)的共享資源中不能含有指針;因?yàn)閷?xiě)執(zhí)行單元可能會(huì)使指針失效,當(dāng)讀執(zhí)行單元正要該指針時(shí),系統(tǒng)就會(huì)。西安電子科技大學(xué)學(xué)院37Seqlockseqlock的實(shí)現(xiàn)思路是,用一個(gè)遞增的整型數(shù)表示

sequence。寫(xiě)操作進(jìn)入臨界區(qū)時(shí),sequence++;退出臨界區(qū)時(shí),sequence再++。寫(xiě)操作還需要獲得一個(gè)鎖(比如mutex),這個(gè)鎖僅用于寫(xiě)寫(xiě)互斥,以保證同一時(shí)間最多只有一個(gè)正在進(jìn)行的寫(xiě)操作。西安電子科技大學(xué)學(xué)院38Seqlock當(dāng)sequence為奇數(shù)時(shí),表示有寫(xiě)操作正在進(jìn)行,這時(shí)讀操作要進(jìn)入臨界區(qū)需要等待,直到sequence變?yōu)榕紨?shù)。讀操作進(jìn)入臨界區(qū)時(shí),需要記錄下當(dāng)前sequence的值,等它退出臨界區(qū)的時(shí)候用記錄的sequence與當(dāng)前sequence做比較,不相等則表示在讀操作進(jìn)入臨界區(qū)期間發(fā)生了寫(xiě)操作,這時(shí)候讀操作讀到的東西是無(wú)效的,需要返回重試。西安電子科技大學(xué)學(xué)院39Seqlock順序鎖的初始化西安電子科技大學(xué)學(xué)院40讀操作unsigned

int

read_seqbegin(const

seqlock_t*

sl);int

read_seqretry(const

seqlock_t*

sl,

unsigned

seq);寫(xiě)操作void

write_seqlock(

seqlock_t*

sl);voidwrite_sequnlock(seqlock_t*

sl);seqlock_init(x);DEFINE_SEQLOCK(x);//動(dòng)態(tài)初始化//靜態(tài)初始化Seqlock西安電子科技大學(xué)學(xué)院41順序鎖的寫(xiě)執(zhí)行單元模式write_seqlock(&lock);......//寫(xiě)操作代碼write_sequnlock(&lock);順序鎖的讀執(zhí)行單元模式unsigned

int

seq_num

=

0;do{seq_num

=

read_seqbegin(&seqlock);//讀操作代碼......}

while(read_seqretry(&seqlock,

seq_num));RCU(Read-Copy-Update)西安電子科技大學(xué)學(xué)院42RCURCU(Read-CopyUpdate),是一種高級(jí)互斥機(jī)制。對(duì)于被RCU保護(hù)的共享數(shù)據(jù)結(jié)構(gòu),讀者不需要獲得任何鎖就可以

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論