1. 程式人生 > 實用技巧 >作業系統 第九節 多程序影象 Multiple Processes

作業系統 第九節 多程序影象 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(優先順序):

FIFO過於簡單,可以為各個程序賦予優先順序,如簡單程序優先處理,但優先順序該如何設定,且優先順序會使某些程序飢餓,仍是問題

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對於多程序的推進不是隨意推進,而是合理的推進