第7章設(shè)備驅(qū)動(dòng)中的并發(fā)_第1頁(yè)
第7章設(shè)備驅(qū)動(dòng)中的并發(fā)_第2頁(yè)
第7章設(shè)備驅(qū)動(dòng)中的并發(fā)_第3頁(yè)
第7章設(shè)備驅(qū)動(dòng)中的并發(fā)_第4頁(yè)
第7章設(shè)備驅(qū)動(dòng)中的并發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第第7 7章章 設(shè)備驅(qū)動(dòng)中的并發(fā)控制設(shè)備驅(qū)動(dòng)中的并發(fā)控制現(xiàn)代操作系統(tǒng)有三大特性:中斷處理、多任務(wù)處理和現(xiàn)代操作系統(tǒng)有三大特性:中斷處理、多任務(wù)處理和多處理器(多處理器(SMP)。這些特性導(dǎo)致當(dāng)多個(gè)進(jìn)程、線程或者)。這些特性導(dǎo)致當(dāng)多個(gè)進(jìn)程、線程或者CPU同時(shí)訪問(wèn)一個(gè)資源時(shí),可能導(dǎo)致錯(cuò)誤,這些錯(cuò)誤是操作同時(shí)訪問(wèn)一個(gè)資源時(shí),可能導(dǎo)致錯(cuò)誤,這些錯(cuò)誤是操作系統(tǒng)運(yùn)行所不允許的。在操作系統(tǒng)中,內(nèi)核需要提供并發(fā)控系統(tǒng)運(yùn)行所不允許的。在操作系統(tǒng)中,內(nèi)核需要提供并發(fā)控制機(jī)制,對(duì)公用資源進(jìn)行保護(hù)。本章將對(duì)保護(hù)這些公用資源制機(jī)制,對(duì)公用資源進(jìn)行保護(hù)。本章將對(duì)保護(hù)這些公用資源的方法進(jìn)行簡(jiǎn)要的介紹。的方法進(jìn)行簡(jiǎn)要的介紹。

2、7.1 7.1 并發(fā)與競(jìng)爭(zhēng)并發(fā)與競(jìng)爭(zhēng)并發(fā)是指在操作系統(tǒng)中,一個(gè)時(shí)間段中有幾個(gè)程序都并發(fā)是指在操作系統(tǒng)中,一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行,但任一個(gè)時(shí)刻點(diǎn)上只有一個(gè)程序在處理機(jī)個(gè)處理機(jī)上運(yùn)行,但任一個(gè)時(shí)刻點(diǎn)上只有一個(gè)程序在處理機(jī)上運(yùn)行。并發(fā)容易導(dǎo)致競(jìng)爭(zhēng)的問(wèn)題。競(jìng)爭(zhēng)就是兩個(gè)或者兩個(gè)上運(yùn)行。并發(fā)容易導(dǎo)致競(jìng)爭(zhēng)的問(wèn)題。競(jìng)爭(zhēng)就是兩個(gè)或者兩個(gè)以上的進(jìn)程同時(shí)訪問(wèn)一個(gè)資源,從而引起資源的錯(cuò)誤。以上的進(jìn)程同時(shí)訪問(wèn)一個(gè)資源,從而引起資源的錯(cuò)誤。7.2 7.2 原子變量操作原子變量操作原子變量操作是原子變量操

3、作是Linux中提供的一種簡(jiǎn)單的同步機(jī)制。中提供的一種簡(jiǎn)單的同步機(jī)制。原子變量操作是一種在操作過(guò)程中不會(huì)被打斷的操作,所以原子變量操作是一種在操作過(guò)程中不會(huì)被打斷的操作,所以在內(nèi)核驅(qū)動(dòng)程序中非常有用。本節(jié)對(duì)在內(nèi)核驅(qū)動(dòng)程序中非常有用。本節(jié)對(duì)Linux中原子變量的操中原子變量的操作進(jìn)行詳細(xì)的分析。作進(jìn)行詳細(xì)的分析。7.2.1 7.2.1 原子變量操作原子變量操作所謂原子變量操作,就是該操作絕不會(huì)在執(zhí)行完畢前所謂原子變量操作,就是該操作絕不會(huì)在執(zhí)行完畢前被任何其他任務(wù)或事件打斷。也就說(shuō),原子變量操作是一種被任何其他任務(wù)或事件打斷。也就說(shuō),原子變量操作是一種不可以被打斷的操作。原子操作需要硬件的支持,

4、因此是架不可以被打斷的操作。原子操作需要硬件的支持,因此是架構(gòu)相關(guān)的,其構(gòu)相關(guān)的,其API和原子類型的定義都定義在內(nèi)核源碼樹(shù)的和原子類型的定義都定義在內(nèi)核源碼樹(shù)的include/asm/atomic.h文件中,它們都使用匯編語(yǔ)言實(shí)現(xiàn),因文件中,它們都使用匯編語(yǔ)言實(shí)現(xiàn),因?yàn)闉镃語(yǔ)言并不能實(shí)現(xiàn)這樣的操作。語(yǔ)言并不能實(shí)現(xiàn)這樣的操作。7.2.2 7.2.2 原子整形操作原子整形操作有時(shí)候需要共享的資源可能只是一個(gè)簡(jiǎn)單的整形數(shù)值。例如有時(shí)候需要共享的資源可能只是一個(gè)簡(jiǎn)單的整形數(shù)值。例如在驅(qū)動(dòng)程序中,需要對(duì)包含一個(gè)在驅(qū)動(dòng)程序中,需要對(duì)包含一個(gè)count的計(jì)數(shù)器。這個(gè)計(jì)數(shù)器表示的計(jì)數(shù)器。這個(gè)計(jì)數(shù)器表示有多少

5、個(gè)應(yīng)用程序打開(kāi)了設(shè)備所對(duì)應(yīng)的設(shè)備文件。通常在設(shè)備驅(qū)有多少個(gè)應(yīng)用程序打開(kāi)了設(shè)備所對(duì)應(yīng)的設(shè)備文件。通常在設(shè)備驅(qū)動(dòng)程序的動(dòng)程序的open()函數(shù)中,將函數(shù)中,將count變量加變量加1。在。在close()函數(shù)中,將函數(shù)中,將count減減1。如果只有一個(gè)應(yīng)用程序執(zhí)行打開(kāi)和關(guān)閉操作,那么這里。如果只有一個(gè)應(yīng)用程序執(zhí)行打開(kāi)和關(guān)閉操作,那么這里的的count計(jì)數(shù)不會(huì)出現(xiàn)問(wèn)題。但是如果有多個(gè)應(yīng)用程序同時(shí)打開(kāi)或計(jì)數(shù)不會(huì)出現(xiàn)問(wèn)題。但是如果有多個(gè)應(yīng)用程序同時(shí)打開(kāi)或者關(guān)閉設(shè)備文件,那么就可能導(dǎo)致者關(guān)閉設(shè)備文件,那么就可能導(dǎo)致count多加或者少加,出現(xiàn)錯(cuò)誤多加或者少加,出現(xiàn)錯(cuò)誤。為了避免這個(gè)問(wèn)題,內(nèi)核提供了一個(gè)原

6、子整形變量,稱為為了避免這個(gè)問(wèn)題,內(nèi)核提供了一個(gè)原子整形變量,稱為atomic_t。7.2.3 7.2.3 原子位操作原子位操作除了原子整數(shù)操作外,還有原子位操作。原子位操作除了原子整數(shù)操作外,還有原子位操作。原子位操作是根據(jù)數(shù)據(jù)的每一位單獨(dú)進(jìn)行操作。根據(jù)體系結(jié)構(gòu)的不同,是根據(jù)數(shù)據(jù)的每一位單獨(dú)進(jìn)行操作。根據(jù)體系結(jié)構(gòu)的不同,原子位操作函數(shù)的實(shí)現(xiàn)也不同。原子位操作函數(shù)的實(shí)現(xiàn)也不同。7.3 7.3 自旋鎖自旋鎖自旋鎖是一種簡(jiǎn)單的并發(fā)控制機(jī)制,其是實(shí)現(xiàn)信號(hào)量自旋鎖是一種簡(jiǎn)單的并發(fā)控制機(jī)制,其是實(shí)現(xiàn)信號(hào)量和完成量的基礎(chǔ)。自旋鎖對(duì)資源有很好的保護(hù)作用,在和完成量的基礎(chǔ)。自旋鎖對(duì)資源有很好的保護(hù)作用,在Li

7、nux驅(qū)動(dòng)程序中進(jìn)程使用,本節(jié)將對(duì)自旋鎖進(jìn)行詳細(xì)的介驅(qū)動(dòng)程序中進(jìn)程使用,本節(jié)將對(duì)自旋鎖進(jìn)行詳細(xì)的介紹。紹。7.3.1 7.3.1 自旋鎖概述自旋鎖概述在在Linux中提供了一些鎖機(jī)制來(lái)避免競(jìng)爭(zhēng)條件,最簡(jiǎn)單中提供了一些鎖機(jī)制來(lái)避免競(jìng)爭(zhēng)條件,最簡(jiǎn)單的一種就是自旋鎖。引入鎖的機(jī)制,是因?yàn)閱为?dú)的原子操作的一種就是自旋鎖。引入鎖的機(jī)制,是因?yàn)閱为?dú)的原子操作不能滿足復(fù)雜的內(nèi)核設(shè)計(jì)需要。例如,當(dāng)一個(gè)臨界區(qū)域要在不能滿足復(fù)雜的內(nèi)核設(shè)計(jì)需要。例如,當(dāng)一個(gè)臨界區(qū)域要在多個(gè)函數(shù)之間來(lái)回運(yùn)行時(shí),原子操作就顯得無(wú)能無(wú)力了。多個(gè)函數(shù)之間來(lái)回運(yùn)行時(shí),原子操作就顯得無(wú)能無(wú)力了。Linxu中一般可以認(rèn)為有兩種鎖,一種是自旋鎖,

8、另一中一般可以認(rèn)為有兩種鎖,一種是自旋鎖,另一種是信號(hào)量。這兩種鎖是為了解決內(nèi)核中遇到的不同問(wèn)題開(kāi)種是信號(hào)量。這兩種鎖是為了解決內(nèi)核中遇到的不同問(wèn)題開(kāi)發(fā)的。其實(shí)現(xiàn)機(jī)制和應(yīng)用場(chǎng)合有所不同,下文將分別對(duì)這兩發(fā)的。其實(shí)現(xiàn)機(jī)制和應(yīng)用場(chǎng)合有所不同,下文將分別對(duì)這兩種鎖機(jī)制進(jìn)行介紹。種鎖機(jī)制進(jìn)行介紹。7.3.2 7.3.2 自旋鎖的使用自旋鎖的使用在在Linux中,自旋鎖的類型為中,自旋鎖的類型為struct spinlock_t。內(nèi)核提。內(nèi)核提供了一系列的函數(shù)來(lái)對(duì)供了一系列的函數(shù)來(lái)對(duì)struct spinlock_t進(jìn)行操作。下面將對(duì)進(jìn)行操作。下面將對(duì)自旋鎖的操作方法進(jìn)行簡(jiǎn)要的介紹。自旋鎖的操作方法進(jìn)行

9、簡(jiǎn)要的介紹。1定義和初始化自旋鎖定義和初始化自旋鎖2鎖定自旋鎖鎖定自旋鎖3釋放自旋鎖釋放自旋鎖4使用自旋鎖使用自旋鎖7.3.3 7.3.3 自旋鎖的使用注意事項(xiàng)自旋鎖的使用注意事項(xiàng)在使用自旋鎖時(shí),有幾個(gè)注意事項(xiàng)需要讀者理解,這在使用自旋鎖時(shí),有幾個(gè)注意事項(xiàng)需要讀者理解,這幾個(gè)注意事項(xiàng)是:幾個(gè)注意事項(xiàng)是:自旋鎖是一種忙等待。自旋鎖是一種忙等待。自旋鎖不能遞歸使用。自旋鎖不能遞歸使用。7.4 7.4 信號(hào)量信號(hào)量本節(jié)介紹鎖的另一種實(shí)現(xiàn)機(jī)制,這種機(jī)制就是本節(jié)介紹鎖的另一種實(shí)現(xiàn)機(jī)制,這種機(jī)制就是Linux中中常用的信號(hào)量。常用的信號(hào)量。Linux中提供了兩種信號(hào)量,一種用于內(nèi)核中提供了兩種信號(hào)量,一種

10、用于內(nèi)核程序中,一種用于應(yīng)用程序中。由于這里講解的是內(nèi)核編程程序中,一種用于應(yīng)用程序中。由于這里講解的是內(nèi)核編程的知識(shí),所以只對(duì)內(nèi)核中的信號(hào)量進(jìn)行詳細(xì)講述。的知識(shí),所以只對(duì)內(nèi)核中的信號(hào)量進(jìn)行詳細(xì)講述。7.4.1 7.4.1 信號(hào)量概述信號(hào)量概述和自旋鎖一樣,信號(hào)量也是保護(hù)臨界資源的一種有用方和自旋鎖一樣,信號(hào)量也是保護(hù)臨界資源的一種有用方法。信號(hào)量與自旋鎖的使用方法基本一樣。與自旋鎖相比,信法。信號(hào)量與自旋鎖的使用方法基本一樣。與自旋鎖相比,信號(hào)量只有當(dāng)?shù)玫叫盘?hào)量的進(jìn)程或者線程才能夠進(jìn)入臨界區(qū),執(zhí)號(hào)量只有當(dāng)?shù)玫叫盘?hào)量的進(jìn)程或者線程才能夠進(jìn)入臨界區(qū),執(zhí)行臨界代碼。信號(hào)量與自旋鎖的最大不同點(diǎn)在于,

11、當(dāng)一個(gè)進(jìn)程行臨界代碼。信號(hào)量與自旋鎖的最大不同點(diǎn)在于,當(dāng)一個(gè)進(jìn)程試圖去獲取一個(gè)已經(jīng)鎖定的信號(hào)量時(shí),試圖去獲取一個(gè)已經(jīng)鎖定的信號(hào)量時(shí),進(jìn)程不會(huì)像自旋鎖一樣進(jìn)程不會(huì)像自旋鎖一樣在遠(yuǎn)處忙等待,在信號(hào)量中采用了另一種方式,這中方式如下在遠(yuǎn)處忙等待,在信號(hào)量中采用了另一種方式,這中方式如下所述。所述。7.4.2 7.4.2 信號(hào)量的實(shí)現(xiàn)信號(hào)量的實(shí)現(xiàn)根據(jù)不同的平臺(tái),其提供的指令代碼有所不同,所以根據(jù)不同的平臺(tái),其提供的指令代碼有所不同,所以信號(hào)量的實(shí)現(xiàn)也有所不同。信號(hào)量的實(shí)現(xiàn)也有所不同。下面詳細(xì)介紹一下這個(gè)結(jié)構(gòu)體的各個(gè)成員變量:下面詳細(xì)介紹一下這個(gè)結(jié)構(gòu)體的各個(gè)成員變量:1lock自旋鎖自旋鎖2count變

12、量變量3等待隊(duì)列等待隊(duì)列7.4.3 7.4.3 信號(hào)量的使用信號(hào)量的使用在在Linux中,信號(hào)量的類型為中,信號(hào)量的類型為struct semaphore。內(nèi)核提。內(nèi)核提供了一系列的函數(shù)來(lái)對(duì)供了一系列的函數(shù)來(lái)對(duì)struct semaphore進(jìn)行操作。下面將進(jìn)行操作。下面將對(duì)信號(hào)量的操作方法進(jìn)行簡(jiǎn)要的介紹。對(duì)信號(hào)量的操作方法進(jìn)行簡(jiǎn)要的介紹。1定義和初始化自旋鎖定義和初始化自旋鎖2鎖定信號(hào)量鎖定信號(hào)量3釋放信號(hào)量釋放信號(hào)量4使用信號(hào)量使用信號(hào)量5信號(hào)量用于同步操作信號(hào)量用于同步操作7.4.4 7.4.4 自旋鎖與信號(hào)量的對(duì)比自旋鎖與信號(hào)量的對(duì)比自旋鎖和信號(hào)量是解決并發(fā)控制的兩個(gè)很重要的方法。在自

13、旋鎖和信號(hào)量是解決并發(fā)控制的兩個(gè)很重要的方法。在使用時(shí),應(yīng)該如何選擇它們其中的一種方法呢?這要根據(jù)被包使用時(shí),應(yīng)該如何選擇它們其中的一種方法呢?這要根據(jù)被包含資源的特定來(lái)確定。含資源的特定來(lái)確定。自旋鎖是一種最簡(jiǎn)單的保護(hù)機(jī)制,從上面的代碼分析中,自旋鎖是一種最簡(jiǎn)單的保護(hù)機(jī)制,從上面的代碼分析中,可以看出自旋鎖的定義只有一個(gè)結(jié)構(gòu)體成員。當(dāng)被包含的代碼可以看出自旋鎖的定義只有一個(gè)結(jié)構(gòu)體成員。當(dāng)被包含的代碼能夠在很短的時(shí)間內(nèi)執(zhí)行完成時(shí),那么使用自旋鎖是一種很好能夠在很短的時(shí)間內(nèi)執(zhí)行完成時(shí),那么使用自旋鎖是一種很好的選擇。因?yàn)樽孕i只是忙等待,不會(huì)進(jìn)入睡眠。要知道,睡的選擇。因?yàn)樽孕i只是忙等待,不會(huì)

14、進(jìn)入睡眠。要知道,睡眠是一種非常浪費(fèi)時(shí)間的操作。眠是一種非常浪費(fèi)時(shí)間的操作。7.5 7.5 完成量完成量在驅(qū)動(dòng)程序開(kāi)發(fā)中,一種常見(jiàn)的情況是:一個(gè)線程需在驅(qū)動(dòng)程序開(kāi)發(fā)中,一種常見(jiàn)的情況是:一個(gè)線程需要等待另一個(gè)線程執(zhí)行完某個(gè)操作后,才能夠繼續(xù)執(zhí)行。上要等待另一個(gè)線程執(zhí)行完某個(gè)操作后,才能夠繼續(xù)執(zhí)行。上面講的信號(hào)量其實(shí)也能夠完成這種工作,不過(guò)其效率不如面講的信號(hào)量其實(shí)也能夠完成這種工作,不過(guò)其效率不如Linux中專門針對(duì)這種情況的完成量機(jī)制。本節(jié)將對(duì)完成量中專門針對(duì)這種情況的完成量機(jī)制。本節(jié)將對(duì)完成量進(jìn)行詳細(xì)的介紹。進(jìn)行詳細(xì)的介紹。7.5.1 7.5.1 完成量概述完成量概述Linux中提供了一種

15、機(jī)制來(lái)實(shí)現(xiàn)一個(gè)線程發(fā)送一個(gè)信號(hào)來(lái)通知中提供了一種機(jī)制來(lái)實(shí)現(xiàn)一個(gè)線程發(fā)送一個(gè)信號(hào)來(lái)通知另一個(gè)線程開(kāi)始完成某個(gè)任務(wù),這種機(jī)制就是完成量。完成量的目另一個(gè)線程開(kāi)始完成某個(gè)任務(wù),這種機(jī)制就是完成量。完成量的目的是告訴一個(gè)線程某個(gè)事件已經(jīng)發(fā)生,可以在此事件基礎(chǔ)上做你想的是告訴一個(gè)線程某個(gè)事件已經(jīng)發(fā)生,可以在此事件基礎(chǔ)上做你想做的另一個(gè)事件了。其實(shí)完成量和信號(hào)量比較類似,但是在這種線做的另一個(gè)事件了。其實(shí)完成量和信號(hào)量比較類似,但是在這種線程通信的情況下,使用完成量有更高的效率。在內(nèi)核中,程通信的情況下,使用完成量有更高的效率。在內(nèi)核中,可以進(jìn)程可以進(jìn)程看見(jiàn)使用完成量的代碼。完成量是一種輕量級(jí)的機(jī)制,這種

16、機(jī)制在看見(jiàn)使用完成量的代碼。完成量是一種輕量級(jí)的機(jī)制,這種機(jī)制在一個(gè)線程希望告訴另一個(gè)線程某個(gè)工作已經(jīng)完成的情況下是非常有一個(gè)線程希望告訴另一個(gè)線程某個(gè)工作已經(jīng)完成的情況下是非常有用的。用的。7.5.2 7.5.2 完成量的實(shí)現(xiàn)完成量的實(shí)現(xiàn)完成量是實(shí)現(xiàn)兩個(gè)任務(wù)之間同步的簡(jiǎn)單方法,在內(nèi)核完成量是實(shí)現(xiàn)兩個(gè)任務(wù)之間同步的簡(jiǎn)單方法,在內(nèi)核中完成量由中完成量由struct completion結(jié)構(gòu)體來(lái)表示。該結(jié)構(gòu)體定義結(jié)構(gòu)體來(lái)表示。該結(jié)構(gòu)體定義在在includelinuxcompletion.h文件中。文件中。下面詳細(xì)介紹一下這個(gè)結(jié)構(gòu)體的兩個(gè)成員變量:下面詳細(xì)介紹一下這個(gè)結(jié)構(gòu)體的兩個(gè)成員變量:1done成員成員2wait成員成員7.5.3 7.5.3 完成量的使用完成量的使用在在Linux中,信號(hào)量的類型為中,信號(hào)量的類型為struct completion。內(nèi)核。內(nèi)核提供了一系列的函數(shù)來(lái)對(duì)提供了一系列的函數(shù)來(lái)對(duì)struct completion進(jìn)行操作。下面進(jìn)行操作。下面將對(duì)完成量的操作方法進(jìn)行簡(jiǎn)要的介紹:將對(duì)完成量的操作方法進(jìn)行簡(jiǎn)要的介紹:1定義和初始化完成量定義和初始化完成量2等待完成量等待完成量3釋放完成量釋放完成量4使用完成量使用完成量7.6 7.6 小結(jié)小結(jié)本章介紹了本章介紹了Li

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論