《Linux性能及調優指南》 Linux進程管理

版權全部:html

原文名稱:《Linux Performance and Tuning Guidelines》linux

原文地址:http://www.redbooks.ibm.com/abstracts/redp4285.html算法

-------------------------------------------------------------------------------------------數組

1.1.1 進程是什麼?
1.1.2 進程生命週期
1.1.3 線程
1.1.4 進程優先級和Nice值
1.1.5 上下文交換
1.1.6 中斷處理
1.1.7 進程狀態
1.1.8 進程內存段
1.1.9 CPU調度器緩存

-------------------------------------------------------------------------------------------網絡

進程管理對於任何一個操做系統來講都是最重要的任務之一。高效的進程管理能保證應用平穩有效的運行。linux的進程管理與UNIX十分類似。它包括進程調度、中斷處理、信號發送、進程優先級、進程切換、進程狀態、進程內存等。在本章節中,我將討論Linux進程管理的原理。它能幫助你更好的瞭解Linux內核是怎樣管理進程來影響系統性能的。數據結構

 

1.1.1 進程是什麼?多線程

 

進程就是執行程序運行在處理器上的一個實例。進程可使用Linux內核所能控制的任何資源來完成它的任務。全部運行在Linux操做系統上的進程都使用一個名叫task_struct的結構來管理,這個結構亦被稱做進程描述符【Process Descriptor】。進程描述符包括進程運行的全部信息如進程ID、進程屬性和構建這個進程所須要的資源。若是你清楚進程的結構,就能瞭解到什麼對於 進程執行和效能來講是重要的。圖1-2展示了進程結構的概要。架構

 

圖 1-2 task_struct結構併發

 

1.1.2 進程生命週期

 

每一個進程都有本身的生命週期如建立、執行、結束和消除。這些階段在系統啓動運行中會被重複無數次。所以從性能角度來看進程生命週期是極其重要的。圖1-3展現進程典型的生命週期

 

 

圖1-3進程典型的生命週期

 

當進程建立一個新的進程,建立進程(父進程)發出fork()系統調用。當一個fork()系統調用被髮出,它將獲得一個關於新進程(子進程)的進 程描述符並設置一個新的進程ID。它會將父進程的進程描述符中全部數據複製到子進程。此時父進程的整個地址空間並無被複制的,因此父子進程會共享相同的 地址空間。exec()系統調用會複製一個新的程序到子進程的地址空間。由於父子進程共享相同的地址空間,因此當新程序寫入數據時會致使分頁錯誤【page fault】的例外發生。這時候內核會分配給子進程一個新的物理分頁。這個推遲的操做被叫作寫時複製 【Copy On Write】。子進程一般是執行本身的程序,與其父進程所執行的有所不一樣。這樣的操做能夠避免沒有必要的系統開銷,由於複製整個地址空間是一個很是慢並且 效率低的操做,它會消耗不少處理器時間和資源。當程序執行完成時,子進程調用exit()系統調用結束。系統調用exit()會釋放進程的大部分數據結構併發送信號通知父進程。此時子進程被稱做僵 屍進程 【zombie process】。在子進程使用wait()系統調用讓父進程知道其已經結束以前,子進程是不會被清除的。當父進程獲得子進程結束的通知後,會當即清除子進程的全部數 據結構並釋放進程描述符。

 

1.1.3 線程

 

線程是由一個單獨進程產生的執行單元。它與同一進程中的其餘線程並行運行。它們能共享同一資源如內存、地址空間、打開的文件等。它們能訪問一樣一組 應用數據。線程也被稱做輕量級進程 (Light Weight Process LWP)。由於它們共享資源,線程不能夠在同一時間修改它們共享的資源。互斥的實現、鎖、序列化等是用戶應用的職責。從性能角度來講,建立線程要比建立進程的開銷小,由於線程在建立時不須要複製資源。另外一方面,進程和線程在調度算法方面上有不少類似的特性。內核在 處理它們時都使用相似的方法。

 

圖1-4 進程和線程

 

在目前Linux的實現中,線程支持可移植操做系統接口(POSIX)。在Linux操做系統中有幾種線程的實現。下面列舉幾種最常使用的線程實 現。

 

▶ LinuxThreads

LinuxThreads自從Linux內核2.0就被做爲默認的線程實現。但LinuxThread有許多實現與POSIX標準不兼容。 Native POSIX Thread Library(NPTL)正在取代LinuxThreads。在將來的Linux企業發行版中將不在支持LinuxThreads。

 

▶ Native POSIX Thread Libray(NPTL)本地POSIX線程庫

NPTL最初是由Red Hat開發。NPTL與POSIX標準更加兼容。利用2.6內核加強特性如新的系統調用clone()、信號處理實現等,它能夠提供較 LinuxThreads更好的性能和伸縮性。

NPTL與LinuxThreads有不少的不兼容之處。一個應用若是依賴於LinuxThreads,可能在NPTL實現中沒法工做。

 

▶ Next Generation POSIX Thread(NGPT)下一代POSIX線程

NGPT是IBM開發的POSIX線程庫的版本。目前處於維護階段,將來也沒有開發計劃。

使用LD_ASSUME_KERNEL環境變量,你能夠設定應用使用哪一個線程庫。

 

1.1.4 進程優先級和Nice值

 

進程優先級 【Process priority】是一個數值,用來讓CPU根據動態優先級和靜態優先級來決定進程執行的順序。一個高優先級的進程能夠得到更多在處理器上運行的機會。內核會根據進程的行爲和特性使用試探算法【Heuristic Algorithm】來動態調高和調低動態優先級。用戶進程能夠經過進程Nice 的 值間接改變靜態優先級。靜態優先級高的進程能夠得到較長的時間片【Time Slice】(進程能運行在處理器有多長時間)。

Linux中Nice值範圍爲19(最低優先級)到-20(最高優先級),默認值爲0。要將Nice值更改成負數,必須經過登陸或使用su命令由 root執行。

 

1.1.5 上下文交換【Context switching】

 

在進程執行過程當中,進程信息存儲在處理器的寄存器和緩存中。這組爲執行中進程而載入寄存器的數據被稱做上下文【Context】。 爲切換進程,當前執行中進程的上下文會被暫存,下一個執行進程的上下文會被還原到寄存器,進程描述符和內核模式堆棧【Kernel mode stack】的區塊會被用來存儲上下文,這個交換過程被叫作上下文交換【Context Switching】。發生過多的上下文交換是很差的,由於處理器每次都要刷新寄存器和緩存爲新進程讓出資源,這會致使性能上的問題。圖1-5 說明了上下文交換是怎樣工做的。

 

 

 

1.1.6 中斷處理

 

中斷處理是優先級最高的任務之一。中斷一般是由I/O設備產生的如網卡、鍵盤、硬盤控制器、串行適配器等。中斷控制會向內核發送一個事件通知(如鍵 盤輸入、以太幀到達等),它指示內核中斷執行中的進程並儘快處理中斷,由於大多數設備須要快速的迴應,這對系統性能是很關鍵的。當一箇中斷信號到達內核 時,內核必須切換當前執行的進程處處理中斷的新進程,這意味着中斷會觸發上下文交換,所以大量的中斷能夠致使系統性能的降低。

在Linux中,有兩種類型的中斷。一種爲硬中斷 【Hard Interrupt】,是由須要迴應的設備產生的(硬盤I/O中斷、網絡適配器中斷,鍵盤中斷,鼠標中斷)。另外一種爲軟中斷 【Soft Interrupt】,用於能夠延後執行的任務(TCP/IP操做,SCSI協議操做等)。你能夠在/proc/interrupts 中 查看到有關硬中斷的信息。

在多處理器環境下,每一個處理器均可以用來處理中斷。將中斷綁定到某一個物理處理能夠提高系統的性能。要了解更詳細的內容,請參考4.4.2「關於中 斷處理的CPU親和力【CPU Affinity】」。

 

1.1.7 進程狀態

 

每一個進程都有它本身的狀態,來顯示進程當前的狀況。在進程執行過程當中其狀態會發生變化。可能狀態有以下幾種:

▶ TASK_RUNNING【運行中】

此狀態表示進程正運行在CPU上或在隊列中等待運行(運行隊列【Run Queue】)。

▶ TASK_STOPPED【中止】

當進程接收到某些信號(例如SIGINT、SIGSTOP)後被暫停就處於此種狀態,該等待的進程在收到恢復信號如SIGCONT後會從新投入運 行。

▶ TASK_INTERRUPTIBLE【可中斷】

在這種狀態下,進程被暫停運行,等待某些狀態的達成。若是一個處於可中斷狀態的進程收到中止的信號,將變動進程的狀態並中斷操做。可中斷狀態進程的 一個典型例子就是等待鍵盤的輸入。

▶ TASK_UNINTERRUPTIBLE【不可中斷】

此狀態基本上與可中斷狀態十分類似。但可中斷狀態進程能夠被中斷,而向一個不可中斷進程發送信號卻不會有任何反應。不可中斷狀態進程的一個典型例子 就是等待硬盤I/O操做。

▶ TASK_ZOMBIE【殭屍】

在進程使用系統調用exit() 退出後,其父進程就會知道。殭屍狀態的進程會等待父進程通知其釋放全部的數據結 構。

 

 
圖1-6 進程狀態

 

殭屍進程

當一個進程收到信號並已經終止,它一般須要一些時間來完成結束前的全部任務(如關閉打開的文件)。在這個一般很短的時間裏,該進程就是一個僵 屍 (Zombie)。

當進程完成全部的關閉任務後,它會向父進程報告其即將終止。但有時殭屍進程並不能將本身終止,在這種狀況狀態會顯示爲(Zombie)。

使用kill命令是不可能結束這樣一個進程的,由於這個進程被認爲已經死掉了。若是你不能清除殭屍,你能夠結束其父進程,這樣殭屍也會隨之消失。然 而若是父進程是init進程,你就不能夠結束它,由於init進程是一個極爲重要的進程。所以你可能須要從新啓動系統來清除這個殭屍進程。

 

1.1.8 進程內存段

 

一個進程須要使用本身的內存區域來執行工做。工做的變化隨狀況和進程用法而定。一個進程能夠有不一樣的工做負載特性和不一樣的數據大小的需求,進程須要 處理數據的大小多種多樣。爲了知足這樣的需求,Linux內核使用動態內存分配機制。進程內存分配結構如圖1-7。

 

 
圖1-7 進程地址空間

 

進程的內存區有幾部分組成

▶ 文字段

用來存儲執行代碼。

▶ 數據段

數據段由三塊區域組成。

― 數據【Data】:存儲已初始化數據如靜態變量。

― BSS :存儲零初始化的數據,數據被初始化爲零。

― 堆【Heap】:這塊區域由malloc()用來按須要分配動態內存。堆向高地址擴張。

▶ 堆棧段

用來存儲本地變量、函數參數、函數返回地址。堆棧段向低地址擴張。

使用pmap 命令能夠顯示用戶進程地址空間的內存分配。你可使用ps 命令 顯示此內存段的大小。參考2.3.10「pmap」和2.3.4「ps和pstree」。

 

 

 

 

1.1.9 Linux CPU調度器

 

計算機的基本功能很是簡單就是計算。爲了計算,這就意味要管理計算資源或處理器和計算任務(被稱做線程或進程)。Linux內核使用與過去CPU調 度器使用的算法O(n)大相徑庭的O(1)算法,這要感謝Lngo Molnar的巨大貢獻。O(1)指的是一種靜態算法,意思就是無論進程的數量有多少,進程的執行時間都是不變的。

這種新的調度器的擴展性很是好,無論進程的數量或處理器的數量有多少,系統的開銷都是很是小的。此算法中使用到兩個進程優先級數組:

▶ 活動的【Active】

▶ 過時的【Expired】

調度器根據進程的優先級和優先攔截率【Prior Blocking Rate】分配時間片,而後它們被以優先級順序置於活動數組【Active Array】中。當時間片耗盡,它們會被分配一個新的時間片並置於過時數組中。當活動數組中全部進程的時間片都所有耗盡,兩個數組會被互換並從新執行。對 於交互進程(相對於實時進程),擁有長時間片的高優先級進程能夠獲得比低優先級進程更多的時間,但這並不意味着低優先級的進程會被置之不理。在企業環境 中,擁有不少的處理器並常常出現大量的線程和進程,這樣作能夠大大提高Linux內核的伸縮性。新的O(1)CPU調度器被設計用於2.6內核,但已被移 植到2.4內核家族。圖1-8說明了Linux CPU調度器是怎樣工做的。

 

 
圖1-8 Linux 2.6內核 O(1)調度器

 

新調度器另外一個大的改進就是支持非一致性內存架構(NUMA)和對稱多線程處理器,如Intel超線程技術。改良後的NUMA支持確保只有當某個節點過載時,負載平衡纔會跨越NUMA節點。This mechanism ensures that traffic over the comparatively slow scalability links in a NUMA system are minimized。儘管在每一個調度節拍【tick】時負載平衡會遍歷調度域羣組【Scheduler Domain Group】中的處理器,但只有在節點過載並請求負載平衡時,負載纔會跨越調度域【Scheduler Domain】轉移。

 

 
圖1-9 O(1) CPU調度器結構

 

譯者注:在翻譯過程當中,深深的感受到進程調度是一項很是複雜的工做。若是想深刻了解2.6內核進程調度還須要多多查看相關資料,下面是一些 關於2.6內核進程調度的文章,有興趣的朋友不妨看看。

Linux 2.6 調度系統分析:http://www.ibm.com/developerworks/cn/linux/kernel/l-kn26sch/index.html 
Linux 的 NUMA 技術:http://www.ibm.com/developerworks/cn/linux/l-numa/index.html 
Linux Scheduling Domains:http://www.ibm.com/developerworks/cn/linux/l-cn-schldom/index.html 
Inside the Linux scheduler:http://www.ibm.com/developerworks/linux/library/l-scheduler/

相關文章
相關標籤/搜索