第二章1信號量及各種鎖_第1頁
第二章1信號量及各種鎖_第2頁
第二章1信號量及各種鎖_第3頁
第二章1信號量及各種鎖_第4頁
第二章1信號量及各種鎖_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

NeusoftInstituteofInformation電子工程系--嵌入式Linux驅(qū)動(dòng)設(shè)備開發(fā)目錄一并發(fā)與競態(tài)三自旋鎖、讀寫鎖四原子操作、等待隊(duì)列二信號量并發(fā)和它的管理

Linux系統(tǒng)的并發(fā)源:多個(gè)用戶空間進(jìn)程在運(yùn)行,它們可能以令人驚訝的方式組合運(yùn)行你的代碼.SMP系統(tǒng)能夠同時(shí)在不同處理器上執(zhí)行你的代碼.內(nèi)核代碼是可搶占的;你的驅(qū)動(dòng)代碼可能在任何時(shí)間失去處理器,代替它的進(jìn)程可能也在你的驅(qū)動(dòng)中運(yùn)行.設(shè)備中斷是能夠?qū)е履愕拇a并發(fā)執(zhí)行的異步事件.內(nèi)核也提供各種延遲代碼執(zhí)行的機(jī)制,例如workqueue,tasklet,定時(shí)器.這些能夠使你的代碼在任何時(shí)間以一種與當(dāng)前進(jìn)程在做的事情無關(guān)的方式運(yùn)行.資源共享的硬規(guī)則任何時(shí)候一個(gè)硬件或軟件資源被超出一個(gè)單個(gè)執(zhí)行線程共享,并且可能存在一個(gè)線程看到那個(gè)資源的不一致時(shí),你必須明確地管理對那個(gè)資源的存取.

當(dāng)內(nèi)核代碼創(chuàng)建一個(gè)會(huì)被內(nèi)核其他部分共享的對象時(shí),這個(gè)對象必須一直存在(并且功能正常)到它知道沒有對它的外部引用存在為止.在大部分情況下,你將發(fā)現(xiàn)內(nèi)核為你處理引用計(jì)數(shù),但是常常有例外.信號量:是一個(gè)單個(gè)整型值,結(jié)合有一對函數(shù),典型地稱為P和V.一個(gè)想進(jìn)入臨界區(qū)的進(jìn)程將在相關(guān)信號量上調(diào)用P;如果信號量的值大于零,這個(gè)值遞減1并且進(jìn)程繼續(xù).相反,如果信號量的值是0(或更小),進(jìn)程必須等待(睡眠)直到別人釋放信號量.解鎖一個(gè)信號量通過調(diào)用V完成;這個(gè)函數(shù)遞增信號量的值,并且,如果需要,喚醒等待的進(jìn)程.信號量和互斥體互斥:

阻止多個(gè)進(jìn)程同時(shí)在同一個(gè)臨界區(qū)內(nèi)運(yùn)行--它們的值將初始化為1.這樣的信號量在任何給定時(shí)間只能由一個(gè)單個(gè)進(jìn)程或者線程持有.以這種模式使用的信號量有時(shí)稱為一個(gè)互斥鎖.

幾乎所有在Linux內(nèi)核中發(fā)現(xiàn)的信號量都用作互斥.

建立臨界區(qū):在任何給定時(shí)間只有一個(gè)線程可以執(zhí)行代碼.

信號量和互斥體信號量信號量在創(chuàng)建時(shí)需要設(shè)置一個(gè)初始值,表示允許有幾個(gè)任務(wù)同時(shí)訪問該信號量保護(hù)的共享資源,初始值為1就變成互斥鎖(Mutex),即同時(shí)只能有一個(gè)任務(wù)可以訪問信號量保護(hù)的共享資源。2.當(dāng)任務(wù)訪問完被信號量保護(hù)的共享資源后,必須釋放信號量,釋放信號量通過把信號量的值加1實(shí)現(xiàn),如果釋放后信號量的值為非正數(shù),表明有任務(wù)等待當(dāng)前信號量,因此要喚醒等待該信號量的任務(wù)。信號量的實(shí)現(xiàn)也是與體系結(jié)構(gòu)相關(guān)的,定義在<asm/semaphore.h>中,structsemaphore類型用來表示信號量。1.定義信號量structsemaphoresem;2.初始化信號量voidsema_init(structsemaphore*sem,intval)該函數(shù)用于初始化設(shè)置信號量的初值,它設(shè)置信號量sem的值為val。信號量信號量voidinit_MUTEX(structsemaphore*sem)該函數(shù)用于初始化一個(gè)互斥鎖,即它把信號量sem的值設(shè)置為1。voidinit_MUTEX_LOCKED(structsemaphore*sem)該函數(shù)也用于初始化一個(gè)互斥鎖,但它把信號量sem的值設(shè)置為0,即一開始就處在已鎖狀態(tài)。定義與初始化的工作可由如下宏一步完成:

DECLARE_MUTEX(name)定義一個(gè)信號量name,并初始化它的值為1。

DECLARE_MUTEX_LOCKED(name)定義一個(gè)信號量name,但把它的初始值設(shè)置為0,即鎖在創(chuàng)建時(shí)就處在已鎖狀態(tài)。信號量信號量獲取信號量 voiddown(structsemaphore*sem)獲取信號量sem,可能會(huì)導(dǎo)致進(jìn)程睡眠,因此不能在中斷上下文使用該函數(shù)。該函數(shù)將把sem的值減1,如果信號量sem的值非負(fù),就直接返回,否則調(diào)用者將被掛起,直到別的任務(wù)釋放該信號量才能繼續(xù)運(yùn)行。intdown_interruptible(structsemaphore*sem)獲取信號量sem。如果信號量不可用,進(jìn)程將被置為TASK_INTERRUPTIBLE類型的睡眠狀態(tài)。該函數(shù)由返回值來區(qū)分是正常返回還是被信號中斷返回,如果返回0,表示獲得信號量正常返回,如果被信號打斷,返回-EINTR。信號量信號量down_killable(structsemaphore*sem)獲取信號量sem。如果信號量不可用,進(jìn)程將被置為TASK_KILLABLE類型的睡眠狀態(tài)。注:down()函數(shù)現(xiàn)已不建議繼續(xù)使用。建議使用down_killable()或down_interruptible()函數(shù)。信號量釋放信號量voidup(structsemaphore*sem)該函數(shù)釋放信號量sem,即把sem的值加1,如果sem的值為非正數(shù),表明有任務(wù)等待該信號量,因此喚醒這些等待者。自旋鎖自旋鎖最多只能被一個(gè)可執(zhí)行單元持有。自旋鎖不會(huì)引起調(diào)用者睡眠,如果一個(gè)執(zhí)行線程試圖獲得一個(gè)已經(jīng)被持有的自旋鎖,那么線程就會(huì)一直進(jìn)行忙循環(huán),一直等待下去,在那里看是否該自旋鎖的保持者已經(jīng)釋放了鎖,“自旋”就是這個(gè)意思。自旋鎖spin_lock_init(x)該宏用于初始化自旋鎖x,自旋鎖在使用前必須先初始化。spin_lock(lock)獲取自旋鎖lock,如果成功,立即獲得鎖,并馬上返回,否則它將一直自旋在那里,直到該自旋鎖的保持者釋放。自旋鎖spin_trylock(lock)試圖獲取自旋鎖lock,如果能立即獲得鎖,并返回真,否則立即返回假。它不會(huì)一直等待被釋放。spin_unlock(lock)釋放自旋鎖lock,它與spin_trylock或spin_lock配對使用。信號量與自旋鎖的使用場合信號量可能允許有多個(gè)持有者,而自旋鎖在任何時(shí)候只能允許一個(gè)持有者。當(dāng)然也有信號量叫互斥信號量(只能一個(gè)持有者),允許有多個(gè)持有者的信號量叫計(jì)數(shù)信號量。信號量適合于保持時(shí)間較長的情況;而自旋鎖適合于保持時(shí)間非常短的情況,在實(shí)際應(yīng)用中自旋鎖控制的代碼只有幾行,而持有自旋鎖的時(shí)間也一般不會(huì)超過兩次上下文切換的時(shí)間,因?yàn)榫€程一旦要進(jìn)行切換,就至少花費(fèi)切出切入兩次,自旋鎖的占用時(shí)間如果遠(yuǎn)遠(yuǎn)長于兩次上下文切換,我們就應(yīng)該選擇信號量。rwlock_t類型,在<linux/spinlokc.h>中定義初始化方法:

rwlock_tmy_rwlock=RW_LOCK_UNLOCKED; /*Staticway*/

rwlock_tmy_rwlock;

rwlock_init(&my_rwlock);/*Dynamicway*/允許多個(gè)讀進(jìn)程同時(shí)進(jìn)入臨界區(qū);寫進(jìn)程必須互斥訪問臨界區(qū)。

讀寫鎖加鎖順序規(guī)則獲得多個(gè)鎖可能是危險(xiǎn)的:Lock1和Lock2,代碼需要同時(shí)都獲取,你有一個(gè)潛在的死鎖.僅僅想象一個(gè)線程鎖住Lock1而另一個(gè)同時(shí)獲得Lock2.接著每個(gè)線程試圖得到它沒有的那個(gè).2個(gè)線程都會(huì)死鎖.當(dāng)多個(gè)鎖必須獲得時(shí),它們應(yīng)當(dāng)一直以同樣順序獲得.

以相反的順序釋放。原子變量對共享變量n_opn_op++;都可能需要加鎖。內(nèi)核提供了一個(gè)原子整數(shù)類型稱為atomic_t

下面的操作為這個(gè)類型定義并且保證對于一個(gè)SMP計(jì)算機(jī)的所有處理器來說是原子的。因?yàn)樗痪幾g成一條單個(gè)機(jī)器指令voidatomic_set(atomic_t*v,inti);atomic_tv=ATOMIC_INIT(0);原子變量voidatomic_add(inti,atomic_t*v);voidatomic_sub(inti,atomic_t*v);voidatomic_inc(atomic_t*v);voidatomic_dec(atomic_t*v);intatomic_inc_and_test(atomic_t*v);intatomic_dec_and_test(atomic_t*v);intatomic_sub_and_test(inti,atomic_t*v);

voidset_bit(nr,void*addr);voidclear_bit(nr,void*addr);等待隊(duì)列在Linux驅(qū)動(dòng)程序設(shè)計(jì)中,可以使用等待隊(duì)列來實(shí)現(xiàn)進(jìn)程的阻塞,等待隊(duì)列可看作保存進(jìn)程的容器,在阻塞進(jìn)程時(shí),將進(jìn)程放入等待隊(duì)列,當(dāng)喚醒進(jìn)程時(shí),從等待隊(duì)列中取出進(jìn)程。Linux2.6內(nèi)核提供了如下關(guān)于等待隊(duì)列的操作:1、定義等待隊(duì)列wait_queue_head_tmy_queue2、初始化等待隊(duì)列init_waitqueue_head(&my_queue)3、定義并初始化等待隊(duì)列DECLARE_WAIT_QUEUE_HEAD(my_queue)等待隊(duì)列4、有條件睡眠wait_event(queue,condition)當(dāng)condition(一個(gè)布爾表達(dá)式)為真時(shí),立即返回;否則讓進(jìn)程進(jìn)入TASK_UNINTERRUPTIBLE模式的睡眠,并掛在queue參數(shù)所指定的等待隊(duì)列上。wait_event_interruptible(queue,condition)當(dāng)condition(一個(gè)布爾表達(dá)式)為真時(shí),立即返回;否則讓進(jìn)程進(jìn)入TASK_INTERRUPTIBLE的睡眠,并掛在queue參數(shù)所指定的等待隊(duì)列上。等待隊(duì)列intwait_event_killable(wait_queue_tqueue,condition)當(dāng)condition(一個(gè)布爾表達(dá)式)為真時(shí),立即返回;否則讓進(jìn)程進(jìn)入TASK_KILLABLE的睡眠,并掛在queue參數(shù)所指定的等待隊(duì)列上。等待隊(duì)列5、無條件睡眠(老版本,建議不再使用)sleep_on(wait_queue_head_t*q)讓進(jìn)程進(jìn)入不可中斷的睡眠,并把它放入等待隊(duì)列q。interruptible_sleep_on(wait_queue_head_t*q)讓

溫馨提示

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

評論

0/150

提交評論