熱搜:win11繞過(guò)硬件限制安裝 一鍵重裝Win10系統(tǒng) 最干凈的u盤(pán)啟動(dòng)盤(pán) 真正純凈版的win7系統(tǒng)
時(shí)間:2015-09-09 15:05:32 作者:zhijie 來(lái)源:系統(tǒng)之家 1. 掃描二維碼隨時(shí)看資訊 2. 請(qǐng)使用手機(jī)瀏覽器訪問(wèn): https://m.xitongzhijia.net/xtjc/20150909/57286.html 手機(jī)查看 評(píng)論 反饋
微軟系統(tǒng)的進(jìn)程管理,無(wú)法就是打開(kāi)任務(wù)管理器,查看進(jìn)程、結(jié)束進(jìn)程、或者創(chuàng)建進(jìn)程。但是在Linux系統(tǒng)中進(jìn)程管理是一件比較復(fù)雜的工作了。本文就來(lái)詳細(xì)介紹一下Linux系統(tǒng)進(jìn)程管理。
普通調(diào)度算法
FCFS
First Come First Service。FIFO方式的調(diào)度策略,先來(lái)后到的服務(wù)方式。
這種方式的優(yōu)勢(shì)是實(shí)現(xiàn)簡(jiǎn)單,也是最容易想到的調(diào)度方案。但是有兩個(gè)重大問(wèn)題:
1.對(duì)短進(jìn)程的運(yùn)行不利
短進(jìn)程必須等到前面長(zhǎng)進(jìn)程執(zhí)行完畢了之后才能運(yùn)行,可能會(huì)等待較長(zhǎng)時(shí)間。
2.對(duì)IO密集型運(yùn)行不利
IO密集型比短進(jìn)程還慘。還不容易排隊(duì)等到他運(yùn)行了,結(jié)果沒(méi)運(yùn)行一會(huì)兒就因?yàn)镮O阻塞去了,等IO操作完畢了之后,還得重新排隊(duì)。
所以這個(gè)算法對(duì)IO密集型的進(jìn)程運(yùn)行效率是極其低下的。
RR
Round Robin。輪詢調(diào)度算法為每個(gè)進(jìn)程分配固定的時(shí)間片,時(shí)間片用完了就必須重新到隊(duì)尾去排隊(duì)。
這樣的設(shè)計(jì)解決了FCFS的第一個(gè)問(wèn)題,相對(duì)而言也部分解決了第2個(gè)問(wèn)題。
但是對(duì)IO密集型進(jìn)程依然解決得不太好,有一個(gè)優(yōu)化的方案就是設(shè)計(jì)兩個(gè)隊(duì)列,將因?yàn)镮O阻塞的進(jìn)程單獨(dú)放一個(gè)隊(duì)列,在選擇下一個(gè)運(yùn)行進(jìn)行的時(shí)候?qū)@個(gè)隊(duì)列的進(jìn)程提權(quán)。
FCFS還有另外一個(gè)比較復(fù)雜的問(wèn)題就是如何選擇時(shí)間片。時(shí)間片過(guò)長(zhǎng)就退化成FCFS算法了,過(guò)短又會(huì)造成切換開(kāi)銷太大。
Prediction
基于預(yù)測(cè)的算法。這類預(yù)測(cè)算法都是假設(shè)我們知道每個(gè)進(jìn)程總共所需要的時(shí)間,以及IO占比信息。
假設(shè)我們能收集到這些信息,可以有如下幾種調(diào)度算法:
1.最短運(yùn)行時(shí)間優(yōu)先
2.最短剩余時(shí)間優(yōu)先
3.綜合已經(jīng)運(yùn)行時(shí)間和剩余時(shí)間來(lái)排序
但是在真實(shí)世界中,一般這個(gè)信息是無(wú)法預(yù)測(cè)的。即使是同一個(gè)進(jìn)程,之前運(yùn)行的情況對(duì)當(dāng)前運(yùn)行的進(jìn)程也不一定有參考價(jià)值。比如cat程序,不同參數(shù)對(duì)運(yùn)行時(shí)間影響很大。
Feedback
這個(gè)是基于Prediction來(lái)優(yōu)化的。如果說(shuō)Prediction是需要預(yù)測(cè)將來(lái)進(jìn)程還需要多少資源的話,F(xiàn)eedback算法就是基于已經(jīng)消耗了的資源來(lái)判斷優(yōu)先級(jí)。
一般來(lái)說(shuō),也就是運(yùn)行時(shí)間越長(zhǎng),優(yōu)先級(jí)越低的調(diào)度算法。
Unix調(diào)度算法
老版調(diào)度算法
這是2.6版本之前的調(diào)度算法,該算法采用優(yōu)化的RR算法,每個(gè)進(jìn)程的優(yōu)先級(jí)算法如下:
p(i) = base(i)+nice(i)+cpu(i)
其中base和nice值都是靜態(tài)固定的,可以由用戶指定的。
cpu是隨著進(jìn)程占用CPU時(shí)間越長(zhǎng)權(quán)重就越低的調(diào)整因子,該因子調(diào)整邏輯如下:
cpu(i) = cpu(i-1)/2
也就是每次進(jìn)程被選中調(diào)度一遍之后,下次對(duì)應(yīng)的cpu因子的值都會(huì)被除以2,降低下次運(yùn)行的權(quán)重。
新版調(diào)度算法
內(nèi)核2.6版本之后重寫(xiě)了調(diào)度算法。也叫O(1)算法。
該算法針對(duì)普通進(jìn)程,設(shè)置了100~139共40個(gè)優(yōu)先級(jí),進(jìn)程屬于哪個(gè)優(yōu)先級(jí)的計(jì)算跟老版調(diào)度算法類似。系統(tǒng)再存儲(chǔ)了一個(gè)位圖,每個(gè)位圖代表一個(gè)優(yōu)先級(jí)是否有等待的進(jìn)程。然后每次都選擇優(yōu)先級(jí)最高的且有進(jìn)程的那個(gè)隊(duì)列選取第一個(gè)進(jìn)程來(lái)運(yùn)行。
SMP的調(diào)度
對(duì)于多處理器的處理,跟上面的調(diào)度算法類似,只是在選擇出進(jìn)程之后,需要再判斷一下給哪個(gè)CPU合適。
一般來(lái)說(shuō),考慮到CPU的本地cache,所以盡量將進(jìn)程調(diào)度到之前運(yùn)行的CPU上運(yùn)行。當(dāng)然,考慮到CPU本身的均衡性,所以肯定還是會(huì)有遷移的工作。
線程相關(guān)
用戶線程&內(nèi)核線程
線程從一開(kāi)始誕生就有兩個(gè)分類:用戶級(jí)線程 和 內(nèi)核級(jí)線程。
我們?cè)贚inux上常見(jiàn)的是內(nèi)核級(jí)線程, 即線程調(diào)度相關(guān)操作都在內(nèi)核里實(shí)現(xiàn), 不太常見(jiàn)的是用戶級(jí)線程。
用戶級(jí)線程的優(yōu)勢(shì)是:
1.線程切換成本低,不用內(nèi)核操作
2.用戶可以自定義線程調(diào)度策略
3.跟操作系統(tǒng)無(wú)關(guān),可以很快移植到另外一臺(tái)機(jī)器上
但是用戶線程也有如下問(wèn)題:
1.一個(gè)線程的阻塞會(huì)影響其他線程,因?yàn)椴僮飨到y(tǒng)看不到別的線程
2.不能很好的利用多核能力,因?yàn)椴僮飨到y(tǒng)會(huì)把一個(gè)內(nèi)核進(jìn)程放到一個(gè)CPU上
目前Linux上只使用內(nèi)核級(jí)線程, Solaris上面兩者都提供。
線程切換
一個(gè)進(jìn)程的上下文主要有如下幾個(gè)部分的信息構(gòu)成:
1.程序計(jì)數(shù)器
2.寄存器信息
3.棧信息
一個(gè)進(jìn)程切換的過(guò)程包含:
1.保存當(dāng)前進(jìn)程的上下文
2.將當(dāng)前進(jìn)程加入操作系統(tǒng)對(duì)應(yīng)隊(duì)列
3.通過(guò)調(diào)度算法選擇另外一個(gè)進(jìn)程
4.調(diào)整虛存映射
5.加載新進(jìn)程的上下文
但是線程切換就不一樣了,之需要切換PC寄存器指向的代碼地址就好,其他操作都不用做,所以線程切換的成本比進(jìn)程切換低多了。
互斥和同步
簡(jiǎn)介
當(dāng)多個(gè)進(jìn)程需要對(duì)同一個(gè)資源進(jìn)行訪問(wèn)的時(shí)候, 為了避免同時(shí)使用這個(gè)資源造成的混亂, 所以需要考慮進(jìn)程間的互斥。
典型的互斥實(shí)現(xiàn)方案如下:
方案介紹
中斷禁用
殺敵一千, 自損八百。雖然能實(shí)現(xiàn)互斥, 但是大大降低了處理器的執(zhí)行效率。而且再多處理器體系結(jié)構(gòu)中, 他還不能達(dá)到互斥
專用機(jī)器指令
往往是通過(guò)一個(gè)不可中斷的指令, 用于原子修改內(nèi)存中的值, 常見(jiàn)的兩個(gè)指令是testset和exchange, 其對(duì)應(yīng)的demo代碼如下圖。該方案的好處是實(shí)現(xiàn)簡(jiǎn)單, 壞處是使用了忙等待, 可能出現(xiàn)饑餓, 可能死鎖, 需要操作系統(tǒng)層進(jìn)行管理和避免。
死鎖的避免
死鎖出現(xiàn)有4個(gè)必要條件:
1.互斥: 資源只能同時(shí)被一個(gè)進(jìn)程使用
2.占有且等待: 一個(gè)進(jìn)程在等待別的資源的時(shí)候, 將繼續(xù)占有其擁有的資源
3.非搶占: 不能強(qiáng)行搶占別人占有的資源
4.循環(huán)等待: 在滿足如上3個(gè)條件的情況下, 出現(xiàn)循環(huán)等待即出現(xiàn)死鎖
要避免死鎖也是從這4個(gè)條件上下手:
1.互斥: 這個(gè)是為了資源功能正常運(yùn)轉(zhuǎn), 無(wú)法避免
2.占有且等待: 讓進(jìn)程一開(kāi)始就申請(qǐng)所有資源才能運(yùn)行。問(wèn)題是效率低下, 進(jìn)程可能要等待很長(zhǎng)時(shí)間, 資源可能被控制很長(zhǎng)時(shí)間, 程序也需要最開(kāi)始就知道需要使用哪些資源;
3.非搶占: 根據(jù)進(jìn)程優(yōu)先級(jí)讓申請(qǐng)資源的進(jìn)程釋放自己之前擁有的資源或者搶占別的進(jìn)程的資源, 靠譜, 唯一的問(wèn)題在于資源的使用不一定有那么容易的保存和恢復(fù)(很多硬件不像處理器那樣可以隨意切換使用進(jìn)程的)
4.循環(huán)等待: 給資源定義一個(gè)序列, 進(jìn)程只能按照序列申請(qǐng)資源, 會(huì)導(dǎo)致進(jìn)程執(zhí)行效率大大降低, 所以主流做法是如下兩種
如上幾種避免辦法都有各種各樣的問(wèn)題, 所以一般不采用, 現(xiàn)在采用最多的方案還是從第4點(diǎn)出發(fā), 只不過(guò)不預(yù)先避免, 而是動(dòng)態(tài)探測(cè):
1.如果一個(gè)進(jìn)程啟動(dòng)或者新增資源需求會(huì)導(dǎo)致死鎖, 則不允許此分配
典型的算法如銀行家算法, 此方法的弊端是需要知道一個(gè)進(jìn)程將來(lái)所需要占用的資源
2.允許所有請(qǐng)求, 周期性的進(jìn)行檢測(cè)死鎖
動(dòng)態(tài)檢測(cè), 運(yùn)行效率高, 但是如果出現(xiàn)死鎖頻率比較高, 則系統(tǒng)運(yùn)行效率會(huì)比較低。
綜合所有的死鎖避免的方法的對(duì)比如下:
編程界面
多進(jìn)程之間的互斥與同步方案有了如上提到的系列硬件支持之后, 就需要考慮操作系統(tǒng)對(duì)有并發(fā)編程的程序員們提供的編程界面了。
信號(hào)量
信號(hào)量是在內(nèi)存中維護(hù)了一個(gè)int, 每次操作對(duì)該int進(jìn)行++或者--。
對(duì)操作者提供了兩個(gè)接口:
1.semWait
該接口檢查int值, 如果該值大于0, 就將該值--, 并進(jìn)入臨界區(qū); 否則就阻塞檢測(cè)該值知道大于0;
2.semSignal
該接口將int值++, 并通知受阻的所有進(jìn)程。通知哪個(gè)進(jìn)程有的采用FIFO策略, 有的采用隨機(jī)策略。
管程
信號(hào)量的方式比較靈活, 讓程序員可以任意控制臨界區(qū)以及交互設(shè)計(jì), 大部分現(xiàn)在程序也都采用了類似的方案, 這是一個(gè)相對(duì)底層但是功能強(qiáng)大的方案。
但是有人提出了信號(hào)量的操作分散, 在模塊中任何位置都可能出現(xiàn), 造成程序編寫(xiě)和維護(hù)困難, 也容易出bug, 所以在70年代, 有人提出了管程的概念, 筆者在實(shí)際工作中尚未使用管程來(lái)實(shí)現(xiàn)進(jìn)程間互斥和同步。
管程底層跟信號(hào)量類似, 只是他把所有加鎖解鎖的邏輯全部封裝在一個(gè)類里面, 所有關(guān)于該臨界資源的操作都在這個(gè)類中以函數(shù)的方式呈現(xiàn), 除了這個(gè)類之外其他任何地方都看不到鎖。這樣就實(shí)現(xiàn)了鎖相關(guān)邏輯集中在一個(gè)地方。
在一個(gè)類里面可以有多把鎖, 跟信號(hào)量類似, 針對(duì)每把鎖, 在該類的函數(shù)里可以用類似semWait和semSignal的接口等待該鎖或者釋放該鎖。
消息傳遞
消息傳遞的方式跟鎖又有些不一樣了, 因?yàn)檫M(jìn)程間同步互斥不外乎就是阻塞和交換信息兩類, 而消息傳遞提供的API就是最底層的API, 把其他邏輯都交給了上層由程序員控制。
其提供的API如下:
1.send(destination, message)
發(fā)送請(qǐng)求
2.receive(source, message)
接收請(qǐng)求
根據(jù)兩個(gè)接口是否阻塞, 一般又分成如下幾類:
1.send和receive都阻塞
一般用于進(jìn)程間緊密同步的時(shí)候使用
2.send不阻塞, receive阻塞
比較常見(jiàn)的方式, send之后可以繼續(xù)做別的事情, 但是receive這頭在收到相關(guān)信息之前, 必須阻塞直到相關(guān)信息確認(rèn)才能繼續(xù)。
3.send和receive都不阻塞
比較少見(jiàn)。
一般現(xiàn)在在分布式系統(tǒng)涉及到跨機(jī)器寫(xiě)作的時(shí)候, 會(huì)使用該方式來(lái)做進(jìn)程間的同步和互斥。
以上就是Linux系統(tǒng)進(jìn)程管理的詳解了,雖然Linux系統(tǒng)的進(jìn)程管理看起來(lái)復(fù)雜,操作起來(lái)也復(fù)雜,但是只要稍微花費(fèi)一點(diǎn)時(shí)間,還能很容易掌握的。當(dāng)然你也可以借助工具來(lái)管理Linux進(jìn)程,具體方法參考:Linux系統(tǒng)Supervisor如何管理進(jìn)程
發(fā)表評(píng)論
共0條
評(píng)論就這些咯,讓大家也知道你的獨(dú)特見(jiàn)解
立即評(píng)論以上留言僅代表用戶個(gè)人觀點(diǎn),不代表系統(tǒng)之家立場(chǎng)