進程概念

  • 馮諾依曼體系結構:現代計算機的硬件體系結構
      五大硬件單元以及典型設備:
  1. 輸入設備:採集獲取數據  鍵盤
  2. 輸出設備:數據輸出 顯示器
  3. 存儲器:內存 (數據緩存). 硬盤和內存的存儲介質是不一樣的;內存的存儲介質是一種易失性介質:數據斷電後丟失。所有設備都是圍繞內存工作,內存是中間的數據緩衝帶---這種硬件體系結構所帶來的軟件行爲
  4. 運算器:中央處理器CPU
  5. 控制器:4+5=中央處理器CPU
    硬件結構決定了軟件行爲:QQ聊天
    所有的硬件都是圍繞內存工作的
 
  • 操作系統:系統內核+外部應用
    內核:管理計算機上的軟硬件資源
    應用:爲了使計算機更加好用
 
  • 操作系統功能:管理(先描述再組織)計算機上的軟硬件資源
      目的:讓計算機更加好用
      操作系統如何管理計算機上的軟硬件資源:先將被管理者描述出來,將這些描述信息組織起來,通過這個描述信息實現對被管理者的管理。(先描述,再組織來進行管理
  • 系統調用接口:操作系統向上提供的系統核心功能的接口
      庫函數和系統調用接口的關係:庫函數封裝了系統調用接口
 
      程序:一系列有序的指令集合--就是程序員編寫的代碼--存儲在硬盤中
      馮諾依曼--所有的數據指令想要被cpu進行處理,第一步就是將代碼和數據加載到內存中
      操作系統如何實現多個程序的調度運行:將這個運行中的程序描述起來,然後將這些描述組織起來進行管理
      通過實現對PCB的調度管理實現對運行中程序的調度運行--對於操作系統來說這個描述信息-pcb就是進程
  • cpu分時機制:cpu以極快的速度切換調度運行所有的程序,造成大家都在同時運行的假象
  • 進程就是PCB(進程控制塊),是操作系統對一個運行中程序的描述,通過這個描述,實現對程序的運行調度。這個pcb/描述在linux中是一個結構體--struct task_struct{...}
  • 描述信息:
  1. 內存指針能夠找到內存中運行的程序代碼以及數據
  2. 上下文數據可以保存程序調度切換時正在處理的數據
  3. 程序計數器保存進程切換時程序即將執行的下一步指令,等等....通過描述這些信息實現控制一個程序的運行。
      操作系統認爲現在要運行哪個程序,則找到對應的pcb,將pcb中保存的各種描述信息加載到cpu寄存器上
      cpu的分時機制:進程在操作系統中是調度切換運行的,每個進程都有一個CPU時間片(一個進程在CPU上的運行時間段),在CPU上時間片運行完畢後則切換到下一個進程
      操作系統該調度哪個進程在cpu上運行,操作系統中有一系列的調度算法
      cpu多核--多個處理核心--每個核心都有自己的寄存器,可以調度一個程序的運行
  • 併發:輪詢處理執行
  • 並行:同時運行/執行
 
  • 創建進程:進程就是pcb,意味着創建一個進程,就是創建一個pcb
  • pid_t  fork(void)--通過複製調用進程(父進程)創建一個新的進程(子進程)
      創建了一個新的pcb,然後從父進程pcb中複製了很多數據過來
     複製的信息:內存指針,程序計數器,上下文數據......
  • 內存指針:子進程與父進程運行的代碼其實是一樣的---指向同一塊物理內存中的數據以及指令
  • 程序計數器/上下文數據:子進程被創建出來後,運行位置與父進程是完全一樣的,下一步即將執行的指令都是從創建子進程成功之後開始的
      創建一個子進程出來,跟父進程乾的事情是一樣的,因爲它們的運行的代碼以及當前的運行位置都是一樣的。
  • 這個函數的返回值對於父子進程是不一樣的:
      在父進程中返回創建的子進程的pid
      在子進程中返回0
  • 通常根據fork的返回值進行代碼的分流,讓父子進程進入不同的判斷執行體完成不同的功能
  • 父子進程代碼共享,數據獨有
 
  • fork的基本使用與返回值認識
      理解爲什麼父子進程運行的代碼和位置都一樣
      理解如何通過返回值進行代碼分流
 
  • pit_t  gitpid(void)--返回調用進程的pid--誰調用就返回誰的pid
 
  • 進程的查看:ps -ef  /  ps-aux
  • 進程狀態: 就緒/運行/阻塞
  • Linux下進程狀態:
  1.  運行態 R:就緒/運行  (正在運行的以及只要拿到時間片就能運行的).  ----運行狀態的進程纔會被操作系統調度在cpu上運行
  2.  可中斷休眠態 S:當前的阻塞能夠被中斷喚醒
  3.  不可中斷休眠態 D:當前的阻塞不會被中斷喚醒,等待條件滿足自己醒來
  4.  停止態 T :停止運行,什麼都不幹
  5.  僵死態 Z: 進程已經退出了,但是資源沒有完全釋放的一種狀態  ---這是一種等待後續處理的狀態
 
  • 命令:ps -aux  / kill /   kill -9 強制殺死進程
 
  • 殭屍進程:處於僵死態的進程--進程已經退出,但是資源沒有完全釋放。
  • 殭屍進程的產生原因子進程先於父進程退出,但是父進程沒有關注子進程的退出狀態,因此子進程成爲殭屍進程。
      子進程先於父進程退出,退出後,爲了保存自身的退出原因(返回值),因此資源沒有完全釋放,但是若父進程沒有關注這個退出狀態,則子進程雖然退出了,但是資源沒有完全釋放,處於僵死狀態,成爲殭屍進程。
  • 資源沒有完全釋放的原因,子進程要保存退出原因
  • 殭屍進程的危害:資源泄露(進程數量資源,結構體資源)  一個用戶所能創建的進程數量(ulimit -a 命令)有限,並且資源沒有完全回收會佔據內存資源
      處理方法:退出父進程(父進程退出,子進程保存退出原因就沒有意義了因此也就被釋放了)
  • 殭屍進程的避免:進程等待(父進程等待子進程退出,獲取退出返回值,釋放子進程資源)
 
      爲什麼要創建一個子進程--子進程乾的事情跟父進程是一樣的 ---創建子進程可以分攤父進程的工作提高效率
 
  • 孤兒進程:父進程先於子進程退出,子進程則成爲孤兒進程,孤兒進程運行在系統後臺,父進程成爲1號進程  init。
      孤兒進程是不會成爲殭屍進程的,因爲1號進程隨時關注子進程退出。
  • 守護進程(精靈進程尾):是一種特殊的孤兒進程,父進程是1號進程,運行在後臺+與終端以及登陸會話脫離關係,不再受影響。
      守護進程通常是一種運行在系統後臺的批處理(默默的做一些循環反覆的事情)程序
 
      守護進程/精靈進程(進程以d結尾):特殊的孤兒進程,脫離終端,會話影響。運行在後臺----調研實現
 
進程狀態:Linux下的進程狀態/殭屍進程的產生原因,危害,處理和避免/孤兒進程產生以及特性/守護進程
 
  • 進程優先級:一個進程對於cpu資源獲取的優先權----權級其實就是一個數字
      交互式進程:直接與用戶進行交互的進程--要求最好能夠更加優先的被cpu處理
      批處理進程:在後臺默默做循環工作的進程
      優先級的作用:讓操作系統運行的更加合理
      CPU密集型程序/io密集型程序
 
  • 環境變量(env 命令查看):配置系統運行環境參數的變量
      環境變量的好處:使系統運行環境配置更加簡單靈活,可以通過設置環境變量給一個進程傳遞參數信息
  • 環境變量的操作
      查看環境變量:env/set(查看所有變量,包含環境變量) / echo(直接打印某一個環境變量的值)
      設置環境變量:export
      刪除環境變量:unset
      $path, 把path當作變量
  • 額外作用:向進程傳遞參數
      操作命令:
      env:查看所有環境變量,相當於是set子集
      echo:打印指定環境變量的內容
      set:查看shell中所有變量信息
      export:設置一個環境變量,
      unset:刪除一個變量
      MYVAL=1000
      export MYVAL
      ./env | grep MYVAL
環境變量特性:具有繼承特性的,子進程默認擁有父進程的環境變量---環境變量也可以用於參數的傳遞
      典型:PATH-系統命令程序的默認搜索路徑
 
  • 代碼中對環境變量的操作
      1、main函數的第三個參數
      int main(int argc,char* argv[],char *env[])--env保存環境變量
      2、通過一個全局變量 extern char** environ;--environ保存環境變量  (在本文件中聲明有這個變量/然而這個變量的具體內容實際上是外部的,標準庫)
      3、char *getenv(const char * name)--通過環境變量名稱獲取一個指定環境變量的數據
 
  • 變量的聲明:告訴編輯器,有這個變量存在(但是這個變量不一定是我們自己定義的,這種聲明使用的變量通常都是一個本文件之外的全局變量)
  • 變量的定義:告訴編輯器,這個變量是什麼樣子的
 
  • 程序地址空間:進程的虛擬地址空間
      地址:對內存單元的編號
      指針:指針就是一個存放地址的變量
      程序是不佔用內存的,運行起來的程序被加載到內存,纔會佔用內存
      一個全局變量,在子進程中修改後打印100,父進程中依然打印1
      數據不同,表示肯定沒有使用同一塊內存空間(一塊內存空間不可能存儲兩個數據) 父子進程打印的數據不同但是地址卻是相同的---矛盾
  • 虛擬地址空間其實就是一個結構體mm_struct;--是一個對內存空間的描述--通過這個描述向進程虛擬出一個完整的,連續的內存空間
     size---表示內存大小
     code_start/code_end:描述代碼段的起始與結束
 
  • 虛擬地址空間:操作系統通過mm_struct結構體爲一個進程描述的虛擬的,連續的,完整的地址空間
  • 爲什麼要描述這麼一個空間      
      爲了能夠實現不讓進程直接訪問物理內存
進程直接訪問物理內存:
內存地址:內存區域的編號
每個進程都有一個自己的進程地址空間
創建子進程--父子進程代碼共享,數據獨有
我們在進程中所訪問到的地址實際是一個虛擬地址
程序地址空間-->進程地址空間-->虛擬地址空間
虛擬地址空間:通過一個結構體描述出一塊完整的連續的線性的地址空間
size/code_start/code_end /data_start/data_end
mm_struct結構體---內存描述符
直接使用物理內存:內存利用率低,缺乏內存訪問控制
 
  • 虛擬地址與物理地址之間的映射:頁表
      頁表主要功能:映射虛擬地址與物理內存的關係/提供內存訪問控制
通過頁表映射實現數據在物理內存上的離散式存儲,提高了內存利用率
通過頁表進行了內存訪問控制
每個進程都有自己的虛擬地址空間,因此進程間保證了獨立性。
 
操作系統通過虛擬地址空間向進程描述了一個完整的連續的虛擬地址空間,供進程使用,但是在物理內存中進程數據的存儲採用離散式存儲(提高內存利用率),並且使用頁表映射虛擬地址與物理地址的映射關係,並且在頁表中可以實現內存訪問控制(標誌位表示內存的訪問權限)
 
  • 如何通過虛擬地址得到物理地址:分段式內存管理/分頁式內存管理/段頁式內存管理
  1. 分段式      內存地址的組成:段號+段內偏移 段表(段號-物理段起始地址) 對程序內存管理比較友好 便於程序員/編譯器的內存管理(優點)
  2. 分頁式      虛擬地址的構成:頁號+頁內偏移   提高內存利用率(優點)
  3. 段頁式(先分段,在每一段採用頁表)      虛擬地址的構成   段號+段內頁號起始+頁內偏移+段表+段內頁表(在每一個分段內又採用分頁式管理)
      集合了分頁式與分段式的優點(優點)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章