1. 程式人生 > 其它 >多程序影象

多程序影象

目錄

多程序影象定義

  • 啟動了的程式就是程序,一次可以啟動多個程式,即多個程序交替推進
  • 每啟動一個程序,作業系統就會用一個專門的結構體PCB來實時記錄這個程序,並按照合理的順序推進程序(分配資源、進行排程)
  • 以上即多程序影象

多程序影象存在於計算機使用始終

  • 計算機啟動過程中,最後是執行main.c函式進行一系列的初始化,並最後有一條指令if(!fork()){init();}建立了第一個程序(某種意義上是第二個,main.c是第一個吧),即啟動了shell,shell本身也是個程序。在windows中是啟動桌面。當然現在很多的linux系統也是有桌面的。
  • 通過shell程序再啟動其他程序
  • 計算機使用過程中,shell是始終存在的,因此多程序影象始終存在。

多程序影象

  • 首先每個程序在記憶體中的實體就是PCB,Process Control Block,程序控制塊,這是一個C語言結構體
  • 一個程序正在執行時,其對應的PCB實時記錄該程序的有關資訊
  • 記憶體中特定位置存放著一個就緒佇列,佇列中的的元素是各個程序的PCB結構體,CPU按照就緒佇列中PCB對應的位置來執行相應程序
  • 在記憶體特定位置還有等待佇列,這些佇列中的PCB對應程序因為還在等待某個硬體裝置而沒法執行,等獲得該裝置之後會進入到就緒佇列中,等待磁碟的就是磁碟等待佇列,等待印表機應該有印表機等待佇列,等待佇列有很多個

多程序的組織:PCB+狀態+佇列

程序的五狀態模型

多程序影象的靈魂:程序交替

  • 以磁碟讀寫為例子
    1. pCur即當前執行程序的PCB,當其啟動磁碟讀寫時,將PCB放到DiskWaitQueue,即磁碟等待佇列,此時程序pCur進入阻塞態
    2. 執行schedule()函式,執行程序切換
    3. schedule()函式首先從就緒佇列ReadyQueue中進行取出下一個需要執行的程序,這一過程(getNext)即程序排程
    4. schedule()中先儲存當前程序的的相關狀態資訊,然後開始執行新的程序
  • 程序交替三個部分:佇列操作+程序排程+切換
    • 程序排程內容很多,經典方法比如FIFO和優先順序佇列等。
    • 程序切換主要內容兩部分,一是儲存當前cpu的狀態,二是切換下一個程序。這一塊需要用匯編實現,因為涉及到各個暫存器的精確控制,C語言無法實現精確控制。

多程序之間相互影響

  • 為了實現多程序影象,很多個程序的PCB必須都放到記憶體中,因為只有在記憶體中才能實現取指執行,但是如果都在記憶體中的話,當前程序的程式碼可能會訪問其他程序的程式碼或資料所在的段,那麼就可能破壞其他程序,為了解決這個問題,就需要多程序的地址空間分離,這是記憶體管理的主要內容。
  • 通過對映表實現程序隔離
    • 主要思想是每個程序都有自己的對映表,當程序1和程序2同時訪問地址100時,實際上通過各自的對映表對映到的實體地址是不同的,這樣就不會相互影響。

多程序之間的合作

  • 典型問題如生產者-消費者問題,生產者程序往一塊記憶體空間中扔資料,消費者程序從中取資料
    • 之所以需要程序合作,是因為cpu的時間片輪轉是不確定的,即可能生產者的程式還沒執行完就進行了程序排程,切換到了消費者程序,然後導致各種混亂。
    • 解決方式是使用鎖,生產者程序對共享資源上鎖,直到程式執行完再解鎖,如果在生產者程式執行完之前就切換到了消費者程序,由於鎖的存在,消費者程序是沒法取資料的,必須等待生產者程序先執行完。
  • 為什麼需要多程序之間的合作呢?本質原因是因為cpu對於多程序是無序推進的,而由於某些合作程序必須是有序的,因此要採取上鎖等措施使得多程序之間有序推進。