作業系統 第九節 多程序影象 Multiple Processes
文章目錄
1 多個程序使用CPU的影象
思考:
如何使用CPU?
讓程式執行起來
如何充分利用CPU?
啟動多個程式,交替執行
啟動了的程式就是程序,所以是多個程序推進
OS只需要把這些程序記錄好,要按照合理的次序推進(分配資源,進行排程),這就是多程序影象
使用者只關心實際的多程序執行的如何,而OS負責具體的多程序推進
多程序圖形從機器啟動到關機結束
在機器啟動過程時,main.c函式中,main初始化各種裝置後,將使用fork()建立第一個程序,即shell/Windows來提供給使用者使用計算機,shell/Windows再啟動其它程序,一個命令啟動一個程序,返回shell再啟動其它程序
Windows中通過工作管理員觀察程序:
OS通過管理程序來管理使用者對計算機的使用
2 多程序如何組織
作業系統感知與組織程序全靠PCB,PCB用來記錄程序資訊的資料結構
多程序通過PCB將程序放在不同佇列中,用狀態轉化來推進多程序
由於CPU只有一個,同一時刻只能為一個程序服務,可以類比為食堂打飯排隊,每個同學是一個程序,佇列最前面的同學正在打飯,即有一個程序正在被CPU服務,後面有一系列程序等待,它們處於就緒佇列,還有一些同學雖然在佇列裡,但是他們找不到飯卡就不能打飯,即該程序需要等待某事件,才能得到CPU的服務
多程序的組織:PCB+狀態+佇列
程序狀態圖:
為了更好管理這些程序,根據它們的狀態進行分類,類比銀行中,視窗中正在辦理業務的就處於執行態,座位上等待的人處於就緒態,人太多去門口等座位的處於阻塞態,結束服務的處於終止態,剛到銀行想辦理業務的處於新建態,這些狀態全都是由OS來管理的,OS管理好這些狀態,對程序的狀態進行改變,就整體推進了多程序
程序狀態圖能給出程序生存期的清晰描述,它是認識作業系統程序管理的一個視窗
3 多程序如何交替切換
交替的三個部分:佇列操作+排程+切換
OS通過schedule()來進行程序間的切換:
schedule()中最為重要的是 getNext(),它將從就緒佇列中取出一個程序,接下來swithc進行當前程序和取出的程序切換,CPU轉去服務取出的程序,getNext負責極為重要的 排程,排程有若干種方式
4 程序排程
交替的三個部分:佇列操作+排程+切換,排程是最為重要的
排程的兩種簡單方式:
1,FIFO(先到先出):
FIFO是公平的策略,但卻沒有考慮到程序執行任務
2,Priority(優先順序):
5 程序切換
切換程序可以類比為,大腦是CPU,你正在讀書即程序1,突然有電話接入,這時需要將讀書的位置即第幾頁第幾行記住儲存在大腦中,即對應程序1的PCB1中,這時來電話的是同事,他向你詢問工作上的一些問題即程序2,你需要將這些資訊從這段回憶的PCB2中拿出來,放到大腦中進行處理,等到處理完這些事,取出PCB1的內容,大腦得知書讀到了第幾頁第幾行,繼續程序1的處理
切換通過switch_to(pCur,pNew)實現:
其核心是暫存器內的值的儲存與賦值
6 多程序之間如何影響
由於多個程序之間的程式都放在記憶體中,當多個程序同時存在時會產生一些問題:
對於上面問題的解決方法:限制對地址100的讀寫,通過對映表進行多程序的地址空間分離
各個程序通過各自的程序對映表來訪問真實的實體記憶體,從而實現地址空間分離,使得多程序在記憶體中和平相處
多程序的地址空間分離是記憶體管理的主要內容,程序管理連帶記憶體管理形成多程序影象
7 多程序之間如何合作
對於一個列印的工作過程:
1,應用程式提交列印任務
2,列印任務被放進列印佇列
3,列印程序從佇列中取出任務
4,列印程序控制印表機列印
對於這個待列印檔案佇列,有的程序想要列印一個.pdf,有的程序想列印一個.word,這些程序的PCB向待列印檔案佇列存放,印表機的列印程序來取,一個個根據排程來處理,這就完成了多程序之間的合作
對於待列印佇列中的7號空位置,程序1和程序2想要處理列印任務,如果不合作可能一開始程序1將它的一部分資訊存入,切換到程序2,程序2將一部分資訊存入一部分,如果程序間不合作,那麼就會亂套
8 消費者和生產者問題
將上面列印的問題抽象一下,將向待列印佇列中放的程序作為生產者,將從待列印對列中取的程序作為消費者,將待列印佇列作為共享資料
生產者生產資料存入共享資料,消費者從共享資料中取出資料處理,共享資料的容量有限作為緩衝區使用
生產者程序向緩衝區中送入資料(in),消費者從緩衝區中取出資料(out),生產者和消費者進行合作操作緩衝區,緩衝區的大小為BUFFER_SIZE,其中counter的存在控制了緩衝區中資料的個數以防止緩衝區溢位,造成資料出錯
但多個程序都放在記憶體中交替執行,counter就會出問題:
上面生產者和消費者對counter處理的理想情況是,counter初始值為5,當生產者送入1個數據到緩衝區,消費者從緩衝區中取出一個數據,counter=counter+1-1=5
但由於多程序交替執行可能會出現:
上面是一種可能的執行過程,初始時刻counter=5,當生產者向buffer中送入了資料後,生產者對應的counter暫存器+1,但是還沒來得及將counter+1寫入counter內,就切換到了消費者程序,此時消費者的counter暫存器得到的counter值仍是5,消費者取出資料,將counter-1存放到消費者counter暫存器中,但此時又切換到了生產者程序,生產者將counter+1寫入counter中,此時counter=6,但又切換到了消費者程序,消費者將counter-1寫入counter中,此時counter=4,但實際上counter=5,這樣就造成了緩衝區的混亂,程序之間的合作就會亂套
9 程序間合作在於程序同步(合理的推進順序)
對於上述的生產者和消費者問題中counter的問題,為了解決多程序切換對counter的改動,所以在寫counter時阻斷其它程序訪問counter
OS對於多程序的推進不是隨意推進,而是合理的推進