導航:首頁 > 操作系統 > linux內核設計與分析

linux內核設計與分析

發布時間:2022-11-25 13:03:30

⑴ 《linux內核探秘深入解析文件系統和設備驅動的架構與設計》epub下載在線閱讀,求百度網盤雲資源

《Linux內核探秘》(高劍林)電子書網盤下載免費在線閱讀

資源鏈接:

鏈接:https://pan..com/s/1X0FBrzSSo0dOW1ZL0dGxqg

提取碼:t247

書名:Linux內核探秘

作者:高劍林

豆瓣評分:6.7

出版社:機械工業出版社

出版年份:2013-12-1

頁數:232

內容簡介:

《Linux內核探秘:深入解析文件系統和設備驅動的架構與設計》從工業需求角度出發,注重效率和實用性,是幫助內核研發及調試、驅動開發等領域工程師正確認識並高效利用Linux內核的難得佳作!作者是騰訊公司資深的Linux內核專家和存儲系統專家,在該領域工作和研究的10餘年間,面試了數百位Linux內核工程師,深知學習Linux內核過程中經常遇到的困惑,以及在工作中容易犯的錯誤。基於這些原因作者撰寫了本書。本書出發點和寫作方式可謂獨辟蹊徑,將Linux內核分為兩個維度,一是基礎部分和應用部分,二是內核架構和內核實現,將兩個維有機統一,深入分析了Linux內核的文件系統、設備驅動的架構設計與實現原理。

《Linux內核探秘:深入解析文件系統和設備驅動的架構與設計》在邏輯上分為三部分:第一部分(第1~2章)首先將內核層劃分為基礎層和應用層,講解了基礎層包含的服務和數據結構,以及應用層包含的各種功能,然後對文件系統的架構進行了提綱挈領的介紹,為讀者學習後面的知識打下基礎;第二部分(第3~9章)從設備到匯流排到驅動,逐步深入,剖析了設備的總體架構、為設備服務的特殊文件系統sysfs、字元設備和input設備、platform匯流排、serio匯流排、PCI匯流排、塊設備的實現原理和工作機制;第三部分(第10~13章)對文件系統的讀寫機制進行了深入分析,最後通過一個真實文件系統ext2,復習本書所有知識點。

作者簡介:

高劍林,資深Linux內核專家、存儲系統專家、嵌入式系統專家。先後就職於華為、UT斯達康、賽門鐵克等公司,從事路由器設備研發、軟體開發和存儲系統研究相關的工作10餘年,經驗非常豐富。現就職於騰訊,負責存儲系統的開發和研究。

⑵ 如何開始學習Linux內核

想要學好Linux,需要具備以下能力:
1. 基本功要扎實
學習任何一種語言,必備的基本功是必須要有的,一方面可以提高效率,另一方面可以拓寬思路。
對於Linux基本知識的學習,對一些初學者來說是枯燥乏味的,可以通過理解再背誦的方式先進行代碼及語法的學習,然後進行實踐操作,必須手動輸入命令行,不要藉助工具,這樣可以更快速有效的掌握Linux。
2. 學以致用
Linux學習的目的是應用,Linux基本知識是一些零散的技術,當沒有應用在項目上時,我們無法理解他的真實價值,所以打好基本功之後,最緊迫的是多做幾個完整的項目,剛開始可以是功能簡單的項目,之後可以選擇稍微復雜的項目,勤於動手,敢於實踐,一定能學好Linux。
3. 學會使用Linux聯機幫助
任何一種教材都不會完全講述Linux知識,一般講的都是比較常用的或者是比較有代表性的知識,但是,我們在項目應用中往往有些功能的實現是需要一些生僻知識和技能的,那麼,如何查找我們所需的知識呢,推薦查閱Linux幫助文檔,主流的Linux都自帶詳細的幫助文檔,很方便解決問題!
4. 在網上找資源
在Linux的學習和應用中,難免會遇到一些沒有思路、不知道如何解決的問題,這時就要藉助網路力量,可以通過搜索引擎搜索查找,也可以咨詢資深技術人員,最終實現問題的解決,這是Linux知識積累的一個重要的途徑!
5. 查閱英文技術文檔
如果想深入學習Linux,查閱英文技術文檔是十分必要的,往往最新的技術都是採用英文文檔的方式發布的,而且更全面,因此,對於Linux人員來說,多看一些Linux技術文檔,對於掌握前沿技術和加深知識是十分有必要的!

⑶ 《Linux內核探秘深入解析文件系統》pdf下載在線閱讀全文,求百度網盤雲資源

《Linux內核探秘深入解析文件系統》網路網盤pdf最新全集下載:
鏈接: https://pan..com/s/10_gfLOVNEpy-TAzONQ0pvA

?pwd=bk5f 提取碼: bk5f
簡介:《Linux內核探秘:深入解析文件系統和設備驅動的架構與設計》從工業需求角度出發,注重效率和實用性,是幫助內核研發及調試、驅動開發等領域工程師正確認識並高效利用Linux內核的難得佳作!作者是騰訊公司資深的Linux內核專家和存儲系統專家,在該領域工作和研究的10餘年間,面試了數百位Linux內核工程師,深知學習Linux內核過程中經常遇到的困惑,以及在工作中容易犯的錯誤。基於這些原因作者撰寫了《Linux內核探秘:深入解析文件系統和設備驅動的架構與設計》。《Linux內核探秘:深入解析文件系統和設備驅動的架構與設計》出發點和寫作方式可謂獨辟蹊徑,將Linux內核分為兩個維度,一是基礎部分和應用部分,二是內核架構和內核實現,將兩個維有機統一,深入分析了Linux內核的文件系統、設備驅動的架構設計與實現原理。

⑷ linux內核同步問題

Linux內核設計與實現 十、內核同步方法

手把手教Linux驅動5-自旋鎖、信號量、互斥體概述

== 基礎概念: ==

並發 :多個執行單元同時進行或多個執行單元微觀串列執行,宏觀並行執行

競態 :並發的執行單元對共享資源(硬體資源和軟體上的全局變數)的訪問而導致的竟態狀態。

臨界資源 :多個進程訪問的資源

臨界區 :多個進程訪問的代碼段

== 並發場合: ==

1、單CPU之間進程間的並發 :時間片輪轉,調度進程。 A進程訪問列印機,時間片用完,OS調度B進程訪問列印機。

2、單cpu上進程和中斷之間並發 :CPU必須停止當前進程的執行中斷;

3、多cpu之間

4、單CPU上中斷之間的並發

== 使用偏向: ==

==信號量用於進程之間的同步,進程在信號量保護的臨界區代碼裡面是可以睡眠的(需要進行進程調度),這是與自旋鎖最大的區別。==

信號量又稱為信號燈,它是用來協調不同進程間的數據對象的,而最主要的應用是共享內存方式的進程間通信。本質上,信號量是一個計數器,它用來記錄對某個資源(如共享內存)的存取狀況。它負責協調各個進程,以保證他們能夠正確、合理的使用公共資源。它和spin lock最大的不同之處就是:無法獲取信號量的進程可以睡眠,因此會導致系統調度。

1、==用於進程與進程之間的同步==

2、==允許多個進程進入臨界區代碼執行,臨界區代碼允許睡眠;==

3、信號量本質是==基於調度器的==,在UP和SMP下沒有區別;進程獲取不到信號量將陷入休眠,並讓出CPU;

4、不支持進程和中斷之間的同步

5、==進程調度也是會消耗系統資源的,如果一個int型共享變數就需要使用信號量,將極大的浪費系統資源==

6、信號量可以用於多個線程,用於資源的計數(有多種狀態)

==信號量加鎖以及解鎖過程:==

sema_init(&sp->dead_sem, 0); / 初始化 /

down(&sema);

臨界區代碼

up(&sema);

==信號量定義:==

==信號量初始化:==

==dowm函數實現:==

==up函數實現:==

信號量一般可以用來標記可用資源的個數。

舉2個生活中的例子:

==dowm函數實現原理解析:==

(1)down

判斷sem->count是否 > 0,大於0則說明系統資源夠用,分配一個給該進程,否則進入__down(sem);

(2)__down

調用__down_common(sem, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);其中TASK_UNINTERRUPTIBLE=2代表進入睡眠,且不可以打斷;MAX_SCHEDULE_TIMEOUT休眠最長LONG_MAX時間;

(3)list_add_tail(&waiter.list, &sem->wait_list);

把當前進程加入到sem->wait_list中;

(3)先解鎖後加鎖;

進入__down_common前已經加鎖了,先把解鎖,調用schele_timeout(timeout),當waiter.up=1後跳出for循環;退出函數之前再加鎖;

Linux內核ARM構架中原子變數的底層實現研究

rk3288 原子操作和原子位操作

原子變數適用於只共享一個int型變數;

1、原子操作是指不被打斷的操作,即它是最小的執行單位。

2、最簡單的原子操作就是一條條的匯編指令(不包括一些偽指令,偽指令會被匯編器解釋成多條匯編指令)

==常見函數:==

==以atomic_inc為例介紹實現過程==

在Linux內核文件archarmincludeasmatomic.h中。 執行atomic_read、atomic_set這些操作都只需要一條匯編指令,所以它們本身就是不可打斷的。 需要特別研究的是atomic_inc、atomic_dec這類讀出、修改、寫回的函數。

所以atomic_add的原型是下面這個宏:

atomic_add等效於:

result(%0) tmp(%1) (v->counter)(%2) (&v->counter)(%3) i(%4)

注意:根據內聯匯編的語法,result、tmp、&v->counter對應的數據都放在了寄存器中操作。如果出現上下文切換,切換機制會做寄存器上下文保護。

(1)ldrex %0, [%3]

意思是將&v->counter指向的數據放入result中,並且(分別在Local monitor和Global monitor中)設置獨占標志。

(2)add %0, %0, %4

result = result + i

(3)strex %1, %0, [%3]

意思是將result保存到&v->counter指向的內存中, 此時 Exclusive monitors會發揮作用,將保存是否成功的標志放入tmp中。

(4) teq %1, #0

測試strex是否成功(tmp == 0 ??)

(5)bne 1b

如果發現strex失敗,從(1)再次執行。

Spinlock 是內核中提供的一種比較常見的鎖機制,==自旋鎖是「原地等待」的方式解決資源沖突的==,即,一個線程獲取了一個自旋鎖後,另外一個線程期望獲取該自旋鎖,獲取不到,只能夠原地「打轉」(忙等待)。由於自旋鎖的這個忙等待的特性,註定了它使用場景上的限制 —— 自旋鎖不應該被長時間的持有(消耗 CPU 資源),一般應用在==中斷上下文==。

1、spinlock是一種死等機制

2、信號量可以允許多個執行單元進入,spinlock不行,一次只能允許一個執行單元獲取鎖,並且進入臨界區,其他執行單元都是在門口不斷的死等

3、由於不休眠,因此spinlock可以應用在中斷上下文中;

4、由於spinlock死等的特性,因此臨界區執行代碼盡可能的短;

==spinlock加鎖以及解鎖過程:==

spin_lock(&devices_lock);

臨界區代碼

spin_unlock(&devices_lock);

==spinlock初始化==

==進程和進程之間同步==

==本地軟中斷之間同步==

==本地硬中斷之間同步==

==本地硬中斷之間同步並且保存本地中斷狀態==

==嘗試獲取鎖==

== arch_spinlock_t結構體定義如下: ==

== arch_spin_lock的實現如下: ==

lockval(%0) newval(%1) tmp(%2) &lock->slock(%3) 1 << TICKET_SHIFT(%4)

(1)ldrex %0, [%3]

把lock->slock的值賦值給lockval;並且(分別在Local monitor和Global monitor中)設置獨占標志。

(2)add %1, %0, %4

newval =lockval +(1<<16); 相當於next+1;

(3)strex %2, %1, [%3]

newval =lockval +(1<<16); 相當於next+1;

意思是將newval保存到 &lock->slock指向的內存中, 此時 Exclusive monitors會發揮作用,將保存是否成功的標志放入tmp中。

(4) teq %2, #0

測試strex是否成功

(5)bne 1b

如果發現strex失敗,從(1)再次執行。

通過上面的分析,可知關鍵在於strex的操作是否成功的判斷上。而這個就歸功於ARM的Exclusive monitors和ldrex/strex指令的機制。

(6)while (lockval.tickets.next != lockval.tickets.owner)

如何lockval.tickets的next和owner是否相等。相同則跳出while循環,否則在循環內等待判斷;

* (7)wfe()和smp_mb() 最終調用#define barrier() asm volatile ("": : :"memory") *

阻止編譯器重排,保證編譯程序時在優化屏障之前的指令不會在優化屏障之後執行。

== arch_spin_unlock的實現如下: ==

退出鎖時:tickets.owner++

== 出現死鎖的情況: ==

1、擁有自旋鎖的進程A在內核態阻塞了,內核調度B進程,碰巧B進程也要獲得自旋鎖,此時B只能自旋轉。 而此時搶占已經關閉,(單核)不會調度A進程了,B永遠自旋,產生死鎖。

2、進程A擁有自旋鎖,中斷到來,CPU執行中斷函數,中斷處理函數,中斷處理函數需要獲得自旋鎖,訪問共享資源,此時無法獲得鎖,只能自旋,產生死鎖。

== 如何避免死鎖: ==

1、如果中斷處理函數中也要獲得自旋鎖,那麼驅動程序需要在擁有自旋鎖時禁止中斷;

2、自旋鎖必須在可能的最短時間內擁有

3、避免某個獲得鎖的函數調用其他同樣試圖獲取這個鎖的函數,否則代碼就會死鎖;不論是信號量還是自旋鎖,都不允許鎖擁有者第二次獲得這個鎖,如果試圖這么做,系統將掛起;

4、鎖的順序規則(a) 按同樣的順序獲得鎖;b) 如果必須獲得一個局部鎖和一個屬於內核更中心位置的鎖,則應該首先獲取自己的局部鎖 ;c) 如果我們擁有信號量和自旋鎖的組合,則必須首先獲得信號量;在擁有自旋鎖時調用down(可導致休眠)是個嚴重的錯誤的;)

== rw(read/write)spinlock: ==

加鎖邏輯:

1、假設臨界區內沒有任何的thread,這個時候任何的讀線程和寫線程都可以鍵入

2、假設臨界區內有一個讀線程,這時候信賴的read線程可以任意進入,但是寫線程不能進入;

3、假設臨界區有一個寫線程,這時候任何的讀、寫線程都不可以進入;

4、假設臨界區內有一個或者多個讀線程,寫線程不可以進入臨界區,但是寫線程也無法阻止後續的讀線程繼續進去,要等到臨界區所有的讀線程都結束了,才可以進入,可見:==rw(read/write)spinlock更加有利於讀線程;==

== seqlock(順序鎖): ==

加鎖邏輯:

1、假設臨界區內沒有任何的thread,這個時候任何的讀線程和寫線程都可以鍵入

2、假設臨界區內沒有寫線程的情況下,read線程可以任意進入;

3、假設臨界區有一個寫線程,這時候任何的讀、寫線程都不可以進入;

4、假設臨界區內只有read線程的情況下,寫線程可以理解執行,不會等待,可見:==seqlock(順序鎖)更加有利於寫線程;==

讀寫速度 CPU > 一級緩存 > 二級緩存 > 內存 ,因此某一個CPU0的lock修改了,其他的CPU的lock就會失效;那麼其他CPU就會依次去L1 L2和主存中讀取lock值,一旦其他CPU去讀取了主存,就存在系統性能降低的風險;

mutex用於互斥操作。

互斥體只能用於一個線程,資源只有兩種狀態(佔用或者空閑)

1、mutex的語義相對於信號量要簡單輕便一些,在鎖爭用激烈的測試場景下,mutex比信號量執行速度更快,可擴展

性更好,

2、另外mutex數據結構的定義比信號量小;、

3、同一時刻只有一個線程可以持有mutex

4、不允許遞歸地加鎖和解鎖

5、當進程持有mutex時,進程不可以退出。

• mutex必須使用官方API來初始化。

• mutex可以睡眠,所以不允許在中斷處理程序或者中斷下半部中使用,例如tasklet、定時器等

==常見操作:==

struct mutex mutex_1;

mutex_init(&mutex_1);

mutex_lock(&mutex_1)

臨界區代碼;

mutex_unlock(&mutex_1)

==常見函數:==

=

⑸ 介紹Linux內核的書求推薦

第一:《Linux內核設計與實現》
簡稱LKD,從入門開始,介紹了諸如進程管理、系統調用、中斷和中斷處理程序、內核同步、時間管理、內存管理、地址空間、調試技術等方面,內容比較淺顯易懂,個人認為是內核新人首先必讀的書籍。新人得有此書,足矣!

第二:《深入理解Linux內核》
簡稱ULK,相比於LKD的內容不夠深入、覆蓋面不廣,ULK要深入全面得多。
前面這兩本,一本提綱挈領,一本全面深入。

第三:《Linux設備驅動程序》
簡稱LDD,驅動開發者都要人手一本了。

第四:《深入理解Linux虛擬內存管理》
簡稱LVMM,是一本介紹Linux虛擬內存管理機制的書。如果你希望深入的研究Linux的內存管理子系統,仔細的研讀這本書無疑是最好的選擇。

第五:《深入理解LINUX網路內幕》
一本講解網路子系統實現的書,通過這本書,我們可以了解到Linux內核是如何實現復雜的網路功能的。
了解更多開源相關,去LUPA社區看看吧。

⑹ Linux內核設計與實現 深入理解linux內核 哪個好

都是好書啊,我都有,linux內核設計比較理論,講述操作系統的一些基本概念但結合linux這個特定的OS,從總體上把握linux內核的設計思想,而深入理解Linux內核則比較具體的講解內核的設計實現引用的代碼比較多,比較細,比較雜,要細細分析。都挺不錯,如何你比較入門,可以先看linux內核設計,但要結合代碼分析,不然也很難入門,深入理解比較難,如果有一定水平,可以入手。

⑺ 有沒有Linux內核源碼指導書籍

1.《Linux內核設計與實現》
本書重在原理。適合入門的最佳圖書。作者是為2.6內核加入了搶占的人,對調度部分非常精通,而調度是整個系統的核心,因此本書是很權威的。

2.《深入理解Linux內核》
此書比上一本多了些細節。是Linux內核黑客在推薦圖書時的首選。寫的比較簡單易懂,適合剛剛接觸LINUX內核的。
此書圖表很多,形象地給出了關鍵數據結構的定義,與《Linux內核源代碼情景分析》相比,本書內容緊湊,不會一個問題講解動輒上百頁,有提綱挈領的功用,但是深度上要遜於《Linux內核源代碼情景分析》。

3.《LINUX設備驅動程序(第3版)》
這書強調動手實踐!但它是講解「設備驅動」的,不是最核心的東西,而且有些東西沒硬體的話無法實踐,可能更適合驅動開發的程序員
其中關於同步與互斥、內存分配的部分,感覺很不錯。

4.《Linux內核源代碼情景分析》
好,很經典,是浙大教授毛德操寫的,可惜成書於2001年之後一直沒有更新。分上下冊。
很多是基於2.4內核講解的需要注意。如果學習的話也建議學習2.6,2.6跟2.4比發生了很多顯著改善,應該學習的。
全書內容博大精深,不是非常好懂,對細節問題描述比較清晰。但是感覺對內核的整體感覺不夠強。另外缺少網路部分的分析。覺得不是很適合初學者。

5.《Linux內核源代碼分析》
點評:面對中高級,這本書很好,對了解操作系統是一本不可多得的好書。
6. 《LINUXKERNEL技術手冊》
參考手冊,很薄,值得一看。

7.《深入Linux內核架構》
這本書針對的是比較新的內核版本2.6.24;內容比較全面,深入淺出。
如果沒有對Linux內核的初步結構的認識,那麼會看得比較吃力。建議可以一邊去翻在國內已經聞名已經久的四本Linux內核著作(《Linux內核原代碼情景分析》、《Linux內核設計與實現》、《深入理解Linux內核》、《Linux設備驅動程序》),再一邊看這本書,把這本書當作一個補充或者當作一個內核框架圖譜說明書來閱讀,收效會更好。

8.《Linux內核完全注釋》
主要描述和注釋了Linux0.11內核全部源代碼。對於初學Linux內核操作系統的人來講,該書能夠引領讀者快速入門,並且能全面了解一個簡單操作系統的工作機理。對於進一步學習現在的Linux內核具有非常大的指導作用。對於學習嵌入式應用的技術人員來講,通過《完全注釋》一書的學習也能迅速融入嵌入式應用領域。

9.《Orange S:一個操作系統的實現》
從只有二十行的引導扇區代碼出發,一步一步地向讀者呈現一個操作系統框架的完成過程。

⑻ 為什麼Linux CFS調度器沒有帶來驚艷的碾壓效果| CSDN博文精選

任何領域,革命性的碾壓式推陳出新並不是沒有,但是概率極低,人們普遍的狂妄在於,總是認為自己所置身的環境正在發生著某種碾壓式的變革,但其實,最終大概率不過是一場平庸。

作者 | dog250

責編 | 劉靜

出品 | CSDN博客

但凡懂Linux內核的,都知道Linux內核的CFS進程調度演算法,無論是從2.6.23將其初引入時的論文,還是各類源碼分析,文章,以及Linux內核專門的圖書,都給人這樣一種感覺,即 CFS調度器是革命性的,它將徹底改變進程調度演算法。 預期中,人們期待它會帶來令人驚艷的效果。

然而這是錯覺。

人們希望CFS速勝,但是分析來分析去, 卻只是在某些方面比O(1)調度器稍微好一點點 。甚至在某些方面比不上古老的4.4BSD調度器。可是人們卻依然對其趨之若鶩,特別是源碼分析,汗牛塞屋!

為什麼CFS對別的調度演算法沒有帶來碾壓的效果呢?

首先,在真實世界,碾壓是不存在的,人與人,事與事既然被放在了同一個重量級梯隊比較,其之間的差別沒有想像的那麼大,根本就不在誰碾壓誰。不能被小說電視劇電影蒙蔽了,此外,徐曉冬大擺拳暴打雷雷也不算數,因為他們本就不是一個梯隊。

任何領域,革命性的碾壓式推陳出新並不是沒有,但是概率極低,人們普遍的狂妄在於,總是認為自己所置身的環境正在發生著某種碾壓式的變革,但其實,最終大概率不過是一場平庸。

最終就出現了角力,僵持。

其次,我們應該看到,CFS調度器聲稱它會給互動式進程帶來福音,在這方面CFS確實比O(1)做得好,但是驚艷的效果來自於粉絲的認同。Linux系統交互進程本來就不多,Linux更多地被裝在伺服器,而在伺服器看來,吞吐是要比交互響應更加重要的。

那麼以交互為主的Android系統呢?我們知道,Android也是採用了CFS調度器,也有一些事BFS,為什麼同樣沒有帶來驚艷的效果呢?

我承認,2008年前後出現CFS時還沒有Android,等到Android出現時,其採用的Linux內核已經默認了CFS調度器,我們看下Android版本,Linux內核版本以及發行時間的關系:

Linux內核在2.6.23就採用了CFS調度器。所以一個原因就是沒有比較。Android系統上,CFS沒有機會和O(1)做比較。

另外,即便回移一個O(1)調度器到Android系統去和CFS做AB,在我看來,CFS同樣不會驚艷,原因很簡單,Android系統幾乎都是交互進程,卻前台進程永遠只有一個,你幾乎感受不到進程的切換卡頓,換句話說,即便CFS對待互動式進程比O(1)好太多,你也感受不到,因為對於手機,平板而言,你切換 APP 的時間遠遠大於進程切換的時間粒度。

那麼,CFS到底好在哪裡?

簡單點說,CFS的意義在於, 在一個混雜著大量計算型進程和IO交互進程的系統中,CFS調度器對待IO交互進程要比O(1)調度器更加友善和公平 。理解這一點至關重要。

其實,CFS調度器的理念非常古老,就說在業界,CFS的思想早就被應用在了磁碟IO調度,數據包調度等領域,甚至最最古老的SRV3以及4.3BSD UNIX系統的進程調度中早就有了CFS的身影,可以說,Linux只是 使用CFS調度器 ,而不是 設計了CFS調度器

就以4.3BSD調度器為例,我們看一下其調度原理。

4.3BSD採用了1秒搶占制,每間隔1秒,會對整個系統進程進行優先順序排序,然後找到優先順序最高的投入運行,非常簡單的一個思想,現在看看它是如何計算優先順序的。

首先,每一個進程j均擁有一個CPU滴答的度量值Cj,每一個時鍾滴答,當前在運行的進程的CPU度量值C會遞增:

當一個1秒的時間區間ii過去之後,Cj被重置,該進程jj的優先順序採用下面的公式計算:

可以計算,在一個足夠長的時間段內,兩個進程運行的總時間比例,將和它們的Base_PrioBase_Prio優先順序的比例相等。

4.3BSD的優先順序公平調度是CPU滴答驅動的。

現在看Linux的CFS,CFS採用隨時搶占制。每一個進程j均攜帶一個 虛擬時鍾VCj ,每一個時鍾滴答,當前進程k的VCk會重新計算,同時調度器選擇VC最小的進程運行,計算方法非常簡單:

可見, Linux的CFS簡直就是4.3BSD進程調度的自驅無級變速版本!

如果你想了解CFS的精髓,上面的就是了。換成語言描述,CFS的精髓就是 「 n個進程的系統,任意長的時間周期TT,每一個進程運行T/n的時間!

當然,在現實和實現中,會有80%的代碼處理20%的剩餘問題,比如如何獎勵睡眠太久的進程等等,但是這些都不是精髓。

綜上,我們總結了:

所以無論從概念還是從效果,Linux CFS調度器均沒有帶來令人眼前一亮的哇塞效果。但是還缺點什麼。嗯,技術上的解釋。

分析和解釋任何一個機制之前,必然要先問,這個機制的目標是什麼,它要解決什麼問題,這樣才有意義。而不能僅僅是明白了它是怎麼工作的。

那麼Linux CFS調度器被採用,它的目標是解決什麼問題的呢?它肯定是針對O(1)演算法的一個問題而被引入並取代O(1),該問題也許並非什麼臭名昭著,但是確實是一枚釘子,必須拔除。

O(1)調度器的本質問題在於 進程的優先順序和進程可運行的時間片進行了強映射!

也就是說,給定一個進程優先順序,就會計算出一個時間片與之對應,我們忽略獎懲相關的動態優先順序,看一下原始O(1)演算法中一個進程時間片的計算:

直觀點顯示:

針對上述問題,2.6內核的O(1)O(1)引入了雙斜率來解決:

直觀圖示如下:

貌似問題解決了,但是如果單單揪住上圖的某一個優先順序子區間來看,還是會有問題,這就是相對優先順序的問題。我們看到,高優先順序的時間片是緩慢增減的,而低優先順序的時間片卻是陡然增減,同樣都是相差同樣優先順序的進程,其優先順序分布影響了它們的時間片分配。

本來是治瘸子,結果腿好了,但是胳臂壞了。

本質上來講,這都源自於下面兩個原因:

固定的優先順序映射到固定的時間片。

相對優先順序和絕對優先順序混雜。

那麼這個問題如何解決?

優先順序和時間片本來就是兩個概念,二者中間還得有個變數溝通才可以。優先順序高只是說明該進程能運行的久一些,但是到底久多少,並不是僅僅優先順序就能決定的,還要綜合考慮,換句話距離來說,如果只有一個進程,那麼即便它優先順序再低,它也可以永久運行,如果系統中有很多的進程,即便再高優先順序的進程也要讓出一些時間給其它進程。

所以,考慮到系統中總體的進程情況,將優先順序轉換為權重,將時間片轉換為份額,CFS就是了。最終的坐標系應該是 權重佔比/時間片 坐標系而不是 權重(或者優先順序)/時間片 。應該是這個平滑的樣子:

看來,Linux CFS只是為了解決O(1)O(1)中一個 「靜態優先順序/時間片映射」 問題的,那麼可想而知,它又能帶來什麼驚艷效果呢?這里還有個「但是」,這個O(1)O(1)調度器的問題其實在計算密集型的守護進程看來,並不是問題,反而是好事,畢竟高優先順序進程可以 無條件持續運行很久而不切換 。這對於吞吐率的提高,cache利用都是有好處的。無非也就侵擾了交互進程唄,又有何妨。

當然,使用調優CFS的時候,難免也要遇到IO睡眠獎懲等剩餘的事情去設計一些trick演算法,這破費精力。

對了,還要設置你的內核為HZ1000哦,這樣更能體現CFS的平滑性,就像它宣稱的那樣。我難以想像,出了Ubuntu,Suse等花哨的桌面發行版之外,還有哪個Linux需要打開HZ1000,伺服器用HZ250不挺好嗎?

關於調度的話題基本就說完了,但是在進入下一步固有的噴子環節之前,還有兩點要強調:

在CPU核數越來越多的時代,人們更應該關心 把進程調度到哪裡CPU核上 而不是 某個CPU核要運行哪個進程

單核時代一路走過來的Linux,發展迅猛,這無可厚非,但是成就一個操作系統內核的並不單單是技術,還有別的。這些當然程序員們很不愛聽,程序員最煩非技術方面的東西了,程序員跟誰都比寫代碼,程序員特別喜歡噴領導不會寫代碼雲雲。

Linux在純技術方面並不優秀,Linux總體上優秀的原因是因為有一群非代碼不明志的程序員在讓它變得越來越優秀,另一方面還要歸功於開源和社區。Linux的學習門檻極低,如果一個公司能不費吹灰之力招聘到一個Linux程序員的話,那它幹嘛還要費勁九牛二虎之力去招聘什麼高端的BSD程序員呢?最終的結果就是,Linux用的人極多,想換也換不掉了。

但無論如何也沒法彌補Linux內核上的一些原則性錯誤。

Linux內核還是以原始的主線為base,以講Linux內核的書為例,經典的Robert Love的《Linux內核設計與實現》,以及《深入理解Linux內核》,在講進程調度的時候,關於多核負載均衡的筆墨都是少之又少甚至沒有,如此經典的著作把很多同好引向了那萬劫不復的代碼深淵。於是乎,鋪天蓋地的CFS源碼分析紛至沓來。

但其實,拋開這么一個再普通不過的Linux內核,現代操作系統進入了多核時代,其核心正是在cache利用上的革新,帶來的轉變就是進程調度和內存管理的革新。review一下Linux內核源碼,這些改變早就已經表現了出來。

可悲的是,關於Linux內核的經典書籍卻再也沒有更新,所有的從傳統學校出來的喜歡看書學習的,依然是抱著10年前的大部頭在啃。

http :// www. ece.ubc.ca/~sasha/papers/eurosys16-final29.pdf

浙江溫州皮鞋濕,下雨進水不會胖。

作者:CSDN博主「dog250」,本文首發於作者CSDN博客https://blog.csdn.net/dog250/article/details/957298 30 。

【END】

閱讀全文

與linux內核設計與分析相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:757
蘋果郵件無法連接伺服器地址 瀏覽:962
phpffmpeg轉碼 瀏覽:671
長沙好玩的解壓項目 瀏覽:144
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:737
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:484
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:381
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:349
風翼app為什麼進不去了 瀏覽:778
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:150
伊克塞爾文檔怎麼進行加密 瀏覽:892
app轉賬是什麼 瀏覽:163