多進程圖像的理解(李治軍操作系統課筆記3)

文章目錄

  • 前言
  • 多進程操作系統的由來
  • 操作系統是如何支持多進程圖像的
  • 前言

    操作系統裏面有兩個非常重要的圖像,一個是多進程圖像,另外一個就是文件管理圖像。這一篇博客來和大家探討一下什麼是多進程圖像,以及操作系統是如何支持多進程圖像的。

    多進程操作系統的由來

    多進程圖像對操作系統非常重要,是操作系統的核心部分,明白了它之後對於操作系統就明白了一大部分。

    那麼多進程圖像是怎麼想出來的呢?
    操作系統的核心就是管理硬件,CPU是計算機的核心硬件,操作系統就是在管理cpu的時候想出了多進程圖像,並且通過多進程圖像將cpu管理好了,CPU管理好了,其他硬件自然帶動起來了,所以說多進程圖像是操作系統的核心圖像。

    cpu管理的直觀想法:

    管理CPU,首先使用cpu,管理它就是要更加高效的使用它。cpu是怎麼用的呢?

    cpu是如何工作的

    CPU的工作原理:如果pc指針是200,那麼cpu就是把200放在地址總線上面,然後內存知道地址總線上面的值是200,就把200這個地址對應的指令通過數據總線發給cpu,然後cpu執行指令,pc指針自動加一,如此往復。

    從這裏可以看出,只要給cpu一個初值就可以工作了。,因爲pc指針會自動加加的,

    這麼一直執行有沒有什麼問題呢?
    功能上是沒有問題的,因爲無論有多少道程序,只要計算機不死機總能執行完;但是在性能上呢?我們都知道程序並不都是計算程序的,有些程序是要訪問io的,如果是都是計算的程序,那麼cpu一直在使用,利用率爲100%,但如果是訪問io的程序呢?在訪問io時,cpu是處於空閒狀態的,如果按照剛纔那種執行方式在訪問io的時候,cpu只能乾等着,這樣就降低了cpu的使用效率了。實際上,這對於cpu的效率影響是非常大的,cpu訪問一次io用的時間可能可以讓cpu執行十萬次計算指令了,畢竟電子設備和機械設備的速度差了很多個數量級。

    有問題存在就會有人去想解決方法。正如“你爲什麼要去登珠穆朗瑪峯?因爲它就在那裏”一樣。這個問題就像你泡茶的時候,在等水開的那段時間你會一直盯着水看嗎?肯定不會,因爲你看不看對結果沒有影響,水並不會因爲你在旁邊看而縮短開的時間。

    於是有人提出一個解決方法,如果程序A在訪問io,那麼就趁這段時間去執行程序B,等程序A的io訪問完了之後再接着執行程序A,這樣就會縮短程序總的執行時間;cpu的利用率也就自然而然的上來了。即“同時”執行多道程序。

    “多道程序、交替執行”是提高cpu效率的一個好辦法。但是如何實現呢?

    在一個cpu上面交替執行多個程序稱爲:併發。如何實現併發?程序A在執行的時候如果碰見io指令就跳到程序B去執行,這個可以通過修改PC指針來實現,等程序A的io執行完了再跳回來也是通過修改PC指針就可以實現,看起來好像很容易實現,但是真的是這樣嗎?看下面一個例子:
    在這裏插入圖片描述
    如果只執行程序1,那麼當add ax,bx 執行完之後,ax裏面的值是3,但是現在如果執行完

mov ax,1
mov bx,2
  • 1
  • 2

之後跳到

mov ax,100
mov bx,200
  • 1
  • 2

再跳到add ax,bx;那麼ax中的值就是300,很明顯不符合程序1的邏輯。因此爲了解決這個問題,操作系統給每個運行中的程序提供一個存放信息的結構:PCB(進程控制塊),這可不是PCB線路板哦;PCB是一種數據結構,存放的是程序跳轉時當前運行程序的信息,比如上面那個例子,在mov bx,2執行完了之後,ax,bx的值、下一條指令的執行地址都會被存在PCB中,等再次執行程序1的時候ax、bx的值仍然是1和2.

注意上面那段話中出現了一個概念:運行中的程序;這是什麼意思,如果程序在磁盤中沒有運行,那麼這種程序叫靜態程序,如果一個程序正在運行,那麼就叫運行中的程序。他們有什麼不一樣呢?

  1. 最直觀的一個在運行,一個沒在運行;
  2. 運行中的程序有開始和結束,因爲不一定會一直運行它;
  3. 運行中的程序還有一個PCB用來存儲當前程序的運行狀態,等等

既然這種運行中的程序與靜態程序有這麼多不一樣地方地方,那麼肯定需要一個概念來描述它,那就是“進程”。

小結一下

如何讓cpu工作?給它一個進程就好了;如何讓cpu高效率的工作?讓它“同時”執行多個程序就好了。

操作系統是如何支持多進程圖像的

多進程給上層用戶的感覺就是:同時啓動了多少個進程
操作系統只需要把這些進程記錄好,按照合理次序推進,讓用戶感覺這幾個進程同時在運行。

前面說過,main.c文件中有這樣兩行:

if (!fork())
{init();}

    這個其實就是創建了第一個進程。就是創建第一個進程,在init中創建了shell,shell對應windows就是啓動了windows桌面。在shell中有如下一段代碼(init()中):

    int main(int argc,char*argv[])
    {
    	while(1)
    	{
    		scanf("%s", cmd);
    		if(!fork())
    		{
    			exec(cmd);
    		}
    		wait();
    	}
    }
    

      大意就是:等待用戶輸入一個命令,然後創建一個進程,運行它,等待下一個命令的到來。直到關機。
      如何證明cpu是多進程執行的?
      在這裏插入圖片描述
      打開任務管理器就好啦,同樣,任務管理器也是一個進程。

      操作系統是怎麼支持多進程圖像的

      1,操作系統是如何組織多進程的?
      操作系統感知、組織進程全靠PCB。如何組織呢?在PCB這個結構體之上形成一些數據結構(隊列);進程可能有幾種狀態,有正在執行的進程(運行態),有準備好了只等cpu來執行的進程(就緒態),有還缺少一些東西沒準備好在等待的進程(阻塞態)。操作系統可以通過進程對應的PCB來知道進程現在所處的狀態。根據進程的狀態轉化可以形成如下的進程狀態圖:

      在這裏插入圖片描述

      新建態表示進程剛創建出來時所處的狀態,終止態表示進程運行完之後所處的狀態。
      箭頭表示操作系統的控制作用,操作系統通過控制進程所處的狀態來推進進程的運行;對進程進行管理。

      根據PCB、狀態形成不同都隊列,放在不同的位置

      2,操作系統如何交替(切換,非常複雜)?
      後面會細講
      包括調度和切換,調度是指從就緒隊列中選擇哪一個進程進入運行態。切換就是如何保留現場之後進入
      新的進程,然後還能回來。
      調度是一個很深刻的問題,本課程不會詳講,有很多算法問題;只會講FIFO:公平,但是沒有考慮進程執行
      的任務的區別。Priority優先級:給每個任務設置優先級
      切換:首先保留上一個進程的執行現場,就是將cpu裏面的東西保存在進程對應的PCB裏面;轉到另外一個進程
      將進程PCB裏面的東西放到CPU裏面去;問題就是這些都要精細的控制,控制每個寄存器

      3,多進程如何影響?
      多個進程之間會相互影響,爲什麼會相互影響呢?因爲多個進程都是存放在內存上面的,如果進程A在執行的時候操作了進程B所在的內存,那麼當進程B運行的時候肯定會出問題呀,因此必須要避免。如何避免呢?對地址進行分離,

      這是內存管理的內容,基本思路是給每一個進程都分配一個地址映射表,進程A中操作的地址經過映射表之後會映射到實際的物理地址,因爲每一個進程都有一個映射表(映射算法不同),所以不同進程代碼中相同的地址映射到的實際地址是不同的,也就是說進程中的地址可以一樣,因爲實際操作的地址不同呀。比如進程A中的[100]經過地址映射到物理地址是80,進程B經過地址映射表之後映射到的地址是20,這樣即使進程A和進程B中都操作了[100]這個地址也無所謂,因爲實際操作的地址是不一樣的。注意這個不是使用CPL和DPL來解決的,CPL和DPL只是用來區分用戶態和核心態的。

      發表評論
      所有評論
      還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
      相關文章