初識程式(一)——作業系統,程式管理,程式狀態

audience_fzn發表於2018-08-09

一、馮諾依曼體系結構

目前我們認識的計算機都是由一個個硬體組成

  • 輸入單元:鍵盤,滑鼠,掃描器等
  • 輸出單元:顯示器,印表機
  • 中央處理器(cpu):含有運算器和控制器

關於馮諾依曼體系,必須強調幾點:

  • 儲存器是指記憶體
  • 不考慮快取的情況,cpu只能對記憶體進行讀寫,不能訪問外設
  • 外設要輸入或輸出資料,也只能從記憶體裡讀取
  • 所有裝置都只能和記憶體打交道

二、作業系統(operate system)

作業系統是一個基本的程式集合,常見的作業系統有Windows,Linux,Unix,安卓等。作業系統包括

  • 核心:(程式管理,記憶體管理,檔案管理,驅動管理)
  • 其他程式(函式庫,shell程式等)

設計os的目的:

  • 與硬體互動,管理所有的軟硬體資源
  • 為使用者程式(應用程式)提供一個良好的執行環境

定位:作業系統是一款純正的“搞管理”的軟體

  • 對上:提供良好的執行環境
  • 對下:進行資源管理

如何理解作業系統的“管理”?

作業系統的管理即將被管理的物件描述起來,組織起來

  • 管理者:作業系統
  • 被管理者:硬體
  • 管理:通過資料進行
  • 作業系統通過驅動程式獲取硬體的資料來管理硬體,作業系統不會直接和硬體打交道

就像一個學校,校長是管理者(os),我們是被管理者(硬體),校長不會直接管理我們,而是通過輔導員等對我們進行管理。校長下達命令,由輔導員來執行(將物件組織起來)。而每個學校的資料庫中都存有每個學生的資訊,各學期的成績等(將物件描述起來)

所以作業系統管理硬體就是:

  1. 描述起來,用struct結構體
  2. 組織起來,用連結串列或其他更高效的資料結構

系統呼叫和庫函式的概念:

  • 在開發角度,作業系統對外表現為一個整體,只會暴露自己的部分介面,供上層開發使用,者部分由作業系統提供的介面,就叫系統呼叫
  • 系統呼叫在使用上,功能比較基礎,對使用者的要求也比較高,所以開發者對部分系統呼叫進行了適度的封裝,從而形成了庫。
  • 庫是對系統操作的一層封裝

vs是整合開發環境,所有的功能全都放在一起

Linux上的每個工具都是獨立的一部分,(vim,gcc,gdb)

三、程式:

作業系統對程式的管理,就是將程式描述起來,將程式組織起來

基本概念:

  • 程式的一個執行例項,正在執行的程式
  • 擔當分配系統資源(cou時間,記憶體)的實體

程式——載入到記憶體(馮諾依曼體系決定)——程式——描述起來(tack_struct)——組織起來(連結串列)

描述程式——PCB:

  • 程式的相關資訊都被放在一個叫做程式控制塊的資料結構中,可以理解為程式屬性的集合
  • Linux作業系統下的PCB被叫做task_struct,task_struct是Linux核心的一種資料結構,他會被價值到記憶體裡並且包含著程式的資訊

task_struct(程式控制塊)的內容:

  1. 識別符號:每個程式都有一個識別符號,可以看成是標籤,用來區分其他程式
  2. 狀態:程式當前的任務狀態,退出程式碼,退出訊號等
  3. 優先順序:相對於其他程式的優先順序
  4. 程式計數器(eip):程式中即將被執行的下一條指令的地址
  5. 記憶體指標:包括程式程式碼和程式的相關資料的指標,還有其他程式共享的記憶體塊的指標
  6. 上下文資料:程式執行時處理器的暫存器中的資料,
  7. I/O狀態資訊:包括顯示的I/O請求,分配給程式的I/O裝置和被程式使用的檔案列表
  8. 記賬資訊:可能包括處理器時間總和,使用的時鐘總和,時間限制,記賬號等
  9. 其他資訊

程式組織:

所有執行在系統裡的程式都以task_struct連結串列( 雙連結串列)的形式存在在核心裡

檢視程式:

程式資訊可以通過/proc系統資料夾檢視,在Linux下用 ps -l命令可以檢視當前目錄下所有程式的部分資訊

同樣我們也可以使用top和ps這些使用者級工具來獲取,如獲取程式

  • 如:我們要獲取PID為1的程式資訊,需要檢視/proc/1這個資料夾
  • ps aux | grep 6151      或    ps axj | grep 6251
  • top aux | grep 6151

獲取程式的識別符號:

  • 程式id :PID;getpid();
  • 父程式id:PPID;getppid();
  • 同一個程式,每次呼叫,程式的pid不同

下面我們通過簡單的程式碼獲取程式的識別符號

通過系統呼叫建立程式——fork初識:

  • fork有倆個返回值
  • 成功:子程式返回0,父程式返回子程式的id(子程式只有一個父程式,而父程式可以有多個子程式)
  • 失敗:子程式返回errno,並不被建立,父程式返回-1;
  • 父子程式程式碼共享,資料個開闢一份空間,私有一份(採用寫時拷貝)
  • fork之後要有if分流

程式狀態:

  • R執行狀態:表明程式要麼正在執行,要麼在執行佇列裡
  • S睡眠狀態:也叫淺度睡眠,可中斷睡眠,意味著等待事件完成
  • D磁碟休眠狀態:也叫深度睡眠,不可中斷睡眠,這個狀態的程式退出會等待IO的結束
  • T停止狀態:可以通過傳送SIGSTOP訊號給程式,用來停止該程式,這個被暫停的程式可以使用訊號SIGCONT讓程式繼續進行
  • X死亡狀態:這個狀態只是一個返回狀態,任務列表中看不到這個狀態的程式
  • 除此之外還有殭屍程式,孤兒程式等

D狀態不執行任務也不能被喚醒的狀態,且不能被kill,所以如果記憶體中有多個D狀態的程式,就會使作業系統記憶體不足,導致系統當機

可以通過訊號修改程式的狀態:

訊號:共64個

  • 1~31(普通訊號)
  • 34~64(實時訊號)

一些常用的訊號:

  • kill -l:檢視所有訊號
  • kill -SIGSTOP pid
  • kill -SIGCONT pid
  • kill -SIGKILLpid   //9號訊號——SIGKILL(尚方寶劍,可以殺死大多程式)

也可以通過訊號的序號使用相應的訊號

  • kill -9 6233  //殺死pid = 6233的程式 

相關文章