日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统进程管理

發布時間:2024/7/23 windows 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统进程管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 進程概述

進程:?一個具有一定的功能的程序在一個數據集合上的一次動態執行過程.

1.1 進程組成

一個進程應該包括:

  • 程序的代碼
  • 程序處理的數據
  • 程序計數器中的值, 指使下一條將運行的指令
  • 一組通用的寄存器的當前值, 堆, 棧
  • 一組系統資源(如打開的文件)

總之, 進程包含了正在運行的一個程序的所有狀態信息.

1.2 進程和程序的聯系

  • 程序是產生進程的基礎
  • 程序的每次運行構成不同的進程
  • 進程是程序功能的體現
  • 通過多次執行, 一個程序可對應多個進程, 通過調用關系, 一個進程可包括多個程序.

進程和程序的區別:

  • 進程是動態的, 程序是靜態的, 程序時有序代碼的集合, 進程是程序的執行, 進程有核心態/用戶態.
  • 進程是暫時的, 程序是永久的, 進程是一個狀態變化的過程, 程序可長久保存
  • 進程與程序的組成不同, 進程的組成包括程序, 數據和進程控制塊(如進程狀態信息)

1.3 進程的特點

  • 動態性: 可動態地創建, 結束進程
  • 并發性: 進程可以被獨立調度并占用處理器運行: 并發并行.
  • 獨立性: 不同進程的工作不相互影響.
  • 制約性: 因訪問共享數據/資源或進程間同步而產生制約

1.4 進程控制結構

進程控制塊: 操作系統管理控制進程運行所用的信息集合. 操作系統用PCB(process control block)來描述進程的基本情況以及運行變化的過程, PCB是進程存在的唯一標志.

進程控制塊的使用:

  • 進程的創建: 為該進程生成一個PCB
  • 進程的終止: 回收它的PCB
  • 進程的組織管理: 通過對PCB的組織管理來實現

PCB含有一下三大類信息:

1. 進程標識信息. 如本進程的標識, 本進程的產生者標識(父進程標識), 用戶標識.

2. 處理器狀態信息保存區. 保存進程的運行現場信息:

  • 用戶可見寄存器, 用戶程序可以使用的數據, 地址等寄存器.
  • 控制和狀態寄存器, 如程序計數器(PC), 程序狀態字(PSW).
  • 棧指針, 過程調用/系統調用/中斷處理和返回時都需要用到它.

3. 進程控制信息:

  • 調度和狀態信息, 用于操作系統調度進程并占用處理器使用.
  • 進程間通信信息, 為支持進程間的與通信相關的各種標識, 信號, 信件等, 這些信息存在接收方的進程控制塊中.
  • 存儲管理信息, 包含有指向本進程映像存儲空間的數據結構.
  • 進程所用資源, 說明由進程打開, 使用的系統資源, 如打開的文件等.
  • 有關數據結構連接信息, 進程可以連接到一個進程隊列中, 或者連接到相關的其他進程的PCB.

PCB的組織方式:

鏈表:?同一狀態的進程其PCB成一鏈表, 多個狀態對應多個不同的鏈表. 各狀態的進程形成不同的鏈表: 就緒鏈表, 阻塞鏈表.

索引表:?同一狀態的進程歸入一個index表(由index指向PCB), 多個狀態對應多個不同的index表. 各狀態的進程形成不同的索引表: 就緒索引表, 阻塞索引表.

2 進程狀態

2.1 進程的生命周期管理

2.1.1 進程創建

引起進程創建的三個主要條件:

  • 系統初始化時
  • 用戶請求創建一個新進程
  • 正在運行的進程執行了創建進程的系統調用

2.1.2 進程運行

內核選擇一個就緒的進程, 讓它占用處理器并執行

2.1.3 進程等待

在以下情況下, 進程等待(阻塞):

  • 請求并等待系統服務, 無法馬上完成
  • 啟動某種操作, 無法馬上完成
  • 需要的數據沒有到達
  • 進程只能自己阻塞自己, 因為只有進程自身才知道何時需要等待某種事件發生.

    2.1.4 進程喚醒

    喚醒進程的原因:

    • 被阻塞進程需要的資源可被滿足
    • 被阻塞進程等待的事件到達
    • 將該進程的PCB插入到就緒隊列

    進程只能被別的進程或操作系統喚醒.

    2.1.5 進程結束

    在以下四種情形下, 進程結束:

    • 正常退出(自愿的)
    • 錯誤退出(自愿的)
    • 致命錯誤(強制性的)
    • 被其他進程所殺(強制性的)

    2.2 進程狀態變化模型

    進程的三種基本狀態:

    進程在生命周期結束前處于且僅處于三種基本狀態之一, 不同系統設置的進程狀態數目不同:

    • 運行狀態: 當一個進程正在處理器上運行時.
    • 就緒狀態: 一個進程獲得了除處理器之外的一切所需資源, 一旦得到處理器即可運行.
    • 等待狀態: 一個進程正在等待某一事件而暫停運行時. 如等待某資源, 等待輸入/輸出完成.

    進程其他的基本狀態:

    • 創建狀態: 一個進程正在被創建, 還沒被轉到就緒狀態之前的狀態.
    • 結束狀態: 一個進程正在從系統中消失時的狀態, 這是因為進程結束或由于其他原因所導致.

    狀態變化:

    • NULL->New: 一個新進程被產生出來執行一個程序.
    • New->Ready: 當進程被創建完成并初始化后, 一切就緒準備運行時, 變為就緒狀態.
    • Ready->Running: 處于就緒狀態的進程被進程調度程序選中后, 就分配到處理器上來運行.
    • Runing->Exit: 當進程表示它已經完成或者因出錯, 當前運行進程會由操作系統結束處理.
    • Runing->Ready: 處于運行狀態的進程在其運行過程中, 由于分配給它的處理器時間片用完而讓出處理器.
    • Runing->Blocked: 當進程請求某樣東西且必須等待時.
    • Blocked->Ready: 當進程要等待的某事件到來時, 它從阻塞狀態變到就緒狀態.

    2.3 進程掛起模型

    進程在掛起狀態時, 意味著進程沒有占用內存空間, 處在掛起狀態的進程映像在磁盤上.

    2.3.1 進程的掛起狀態

    掛起狀態有兩種:

    • 阻塞掛起狀態: 進程在外存并等待某事件的出現.
    • 就緒掛起狀態: 進程在外存, 但只要進入內存, 即可運行.

    2.3.2 掛起相關的狀態轉換

    把一個進程從內存轉到外存(掛起), 可能有以下幾種情況:

    • 阻塞到阻塞掛起: 沒有進程處于就緒狀態或就緒進程進程要求更多內存資源時, 會進行這種轉換, 以提交新進程或進行就緒進程.
    • 就緒到就緒掛起: 當有高優先級阻塞(系統認為會很快就緒的)進程和低優先就緒進程時, 系統會選擇掛起低優先級就緒進程.
    • 運行到就緒掛起: 對搶先式分時系統, 當有高優先級阻塞掛起進程因事件出現而進入就緒狀態時, 系統可能會把運行進程轉到就緒掛起狀態.

    在外存時的狀態轉換:

    • 阻塞掛起到就緒掛起: 當有阻塞掛起進程因相關事件出現時, 系統會把阻塞掛起進程轉換為就緒掛起進程.

    解掛/激活(把一個進程從外存轉到內存)的情況:

    • 就緒掛起到就緒: 沒有就緒進程或掛起進程優先級高于就緒進程時, 會進行這種轉換.
    • 阻塞掛起到阻塞: 當一個進程釋放足夠內存時, 系統會把一個高優先級阻塞掛起(系統認為會很快出現所等待的事件)進程轉換為阻塞進程.

    2.4 狀態隊列

    • 由操作系統來維護一組隊列, 用來表示系統當中所有進程的當前狀態
    • 不同的狀態分別用不同的隊列來表示(就緒隊列, 各種類型的阻塞隊列)
    • 每個進程的PCB都根據他的狀態加入到相應的隊列當中, 當一個進程的狀態發生變化時, 它的PCB從一個狀態隊列中脫離出來, 加入到另外一個狀態隊列.

    (此處為個人理解, 應該只是PCB數據結構的指針進行各個隊列的出隊/入隊.)

    3 線程

    3.1 線程的使用意義

    需要提出一種新的實體, 滿足以下特性:

    • 實體之間可以并發地執行
    • 實體之間共享相同的地址空間

    3.2 線程

    3.2.1 線程特性

    線程可以定義為: 進程當中的一條執行流程.

    從兩個方面來重新理解進程:

    • 從資源組合的角度: 進程把一組相關的資源組合起來, 構成了一個資源平臺(環境), 包括地址空間(代碼段, 數據段), 打開的文件等各種資源.
    • 從運行的角度: 代碼在這個資源平臺上的一條執行流程(線程).

    線程的優點:

    • 一個進程中可以同時存在多個線程
    • 各個線程之間可以并發地執行
    • 各個線程之間可以共享地址空間和文件等資源

    線程的缺點:

    • 一個線程崩潰, 會導致其所屬進程的所有線程崩潰.

    3.2.2 不同操作系統對線程的支持

    3.2.3 線程所需的資源

    3.2.4 線程與進程的比較

    • 進程是資源分配單位, 線程是CPU調度單位
    • 進程擁有一個完整的資源平臺, 而線程只獨享必不可少的資源, 如寄存器和棧
    • 線程同樣具有就緒, 阻塞和執行三種基本狀態, 同樣具有狀態之間的轉換關系
    • 線程能減少并發執行的時間和空間開銷:
    • 線程的創建時間比進程短
    • 線程的終止時間比進程短
    • 同一進程內的線程切換時間比進程短
    • 由于同一進程的各線程見共享內存和文件資源, 可直接進行不通過內核的通信.

    3.3 線程的實現

    主要有三種線程的實現方式:

    • 用戶線程: 在用戶空間實現
    • 內核線程: 在內核中實現
    • 輕量級進程: 在內核中實現, 支持用戶線程

    用戶線程和內核線程的對應關系:

    • 多對一
    • 一對一
    • 多對多

    3.3.1 用戶線程

    在用戶空間實現的線程機制, 它不依賴于操作系統的內核, 由一組用戶級的線程庫函數來完成線程的管理, 包括進程的創建, 終止, 同步和調度等.

    • 由于用戶線程的維護由相應進程來完成(通過線程庫函數), 不需要操作系統內核了解用戶線程的存在, 可用于不支持線程技術的多進程操作系統.
    • 每個進程都需要它私有的線程控制塊(TCB)列表, 用來跟蹤記錄它的各個線程的狀態信息(PC, 棧指針, 寄存器), TCB由線程庫函數來維護.
    • 用戶線程的切換也是由線程庫函數來完成, 無需用戶態/核心態切換, 所以速度特別快.
    • 允許每個進程擁有自定義的線程調度算法.

    用戶線程的缺點:

    • 阻塞性的系統調用如何實現? 如果一個線程發起系統調用而阻塞, 則整個進程在等待.
    • 當一個線程開始運行后, 除非它主動地交出CPU的使用權, 否則它所在的進程當中的其他線程將無法運行.
    • 由于時間片分配給進程, 故與其他進程比, 在多線程執行時, 每個線程得到的時間片較少, 執行會較慢.

    3.3.2 內核線程

    是指在操作系統的內核當中實現的一種線程機制, 由操作系統的內核來完成線程的創建, 終止和管理.

    • 在支持內核線程的操作系統中, 由內核來維護進程和線程的上下文信息(PCB和TCB)
    • 線程的創建, 終止和切換都是通過系統調用/內核函數的方式來進行, 由內核來完成. 因此系統開銷較大.
    • 在一個進程當中, 如果某個內核線程發起系統調用而被阻塞, 并不會影響其他內核線程的運行.
    • 時間片分給線程, 多線程的進程獲得更多CPU時間
    • Windows NT和Windows 2000/XP支持內核線程.

    3.3.3 輕量級進程

    它是內核支持的用戶線程, 一個進程可有一個或者多個輕量級進程, 每個輕量級進程由一個單獨的內核線程來支持.(Solaris/Linux)

    3.4 多線程編程接口舉例

    4 進程控制

    4.1 進程切換

    停止當前運行進程(從運行狀態改變成其他狀態)并且調度其他進程(轉變成運行狀態)

    • 必須在切換之前存儲許多部分的進程上下文
    • 必須能夠在之后恢復他們, 所以進程不能顯示它曾經被暫停過
    • 必須快速(上下文轉換是非常頻繁的)

    需要存儲的上下文:

    • 寄存器(PC, SP, ..), CPU狀態, ...
    • 一些時候可能會費時, 所以我們應該盡可能避免

    進程控制塊PCB: 內核的進程狀態記錄

    • 內核為每個進程維護了對應的進程控制塊
    • 內核將相同狀態的進程的PCB放置在同一個隊列(就緒隊列, I/O等待隊列--每一個設備一個隊列, 僵尸隊列等)

    4.2 進程創建

    進程創建是操作系統提供給用戶使用的系統調用, 完成新進程的創建工作.

    不同系統的進程創建API不同, 如下:

    • Windows進程創建API: CreateProcess(filename)
    • Unix/Linux進程創建系統調用: fork/exec, 其中fork完成把一個進程復制成兩個進程, 兩個進程只有進程ID不同(PID), 復制完成后exec把新程序加載進來重寫當前進程(PID沒有改變)

    Unix/Linux進程創建系統調用示例如下:

    int pid = fork(); //創建子進程//父進程執行完這一行之后, 創建出來的子進程和本身的父進程都會//繼續向下執行, 只不過此時子進程的pid是0, 父進程返回的是子//的pid if (pid == 0) {//此時說明是子進程, 就掉用exec執行想要執行的文件 }

    fork()創建一個繼承的子進程:

    • 復制父進程的所有變量和內存
    • 復制父進程的所有CPU寄存器(有一個寄存器例外)

    fork()的地址空間復制:

    • fork()執行過程對于子進程而言, 是在調用時間對父進程地址空間的一次復制(對于父進程fork()返回child PID, 對于子進程返回值為0).
    • 系統調用exec()加載新程序取代當前運行進程.

    4.3 進程加載

    在Linux中會調用exec來加載新程序取代當前運行進程:

    • exec()調用允許一個進程"加載"一個不同的程序并且在main開始執行(事實上 _start)
    • 它允許一個進程指定參數的數量(argc: argument count)和它字符串參數數組(argv).
    • 如果調用成功, 進程PID還是原來的PID, 但是運行的程序改變了(原來運行的是父進程程序, 調用后運行加載的程序)
    • 其代碼段, stack, heap都會重寫

    fork()的優化:

    首先由前面已知, fork()的簡單實現:

    • 對子進程分配內存
    • 復制父進程的內存和CPU寄存器到子進程里
    • 開銷昂貴

    但是, 在99%的情況里, 我們在調用fork()之后會繼續調用exec(), 也就意味著:

    • 在fork()操作中內存復制是沒有作用的
    • 子進程將可能關閉打開的文件和鏈接
    • 開銷因此是高的
    • 為什么不能結合它們在一個調用中

    vfork() --- 早期Unix系統提供

    • 一個創建進程的系統調用, 不需要創建一個同樣的內存映像
    • 一些時候稱為輕量級fork()
    • 子進程應該幾乎立即調用exec()
    • 現在不再使用如果我們使用Copy on Write(COW)技術

    4.4 進程的等待與退出

    wait()系統調用是被父進程用來等待子進程的結束.

    當一個進程結束之后, 一些資源(比如PCB等)是無法進行自我回收的.

    一個子進程向父進程返回一個值, 所以父進程必須接受這個值并處理, wait()系統調用擔任這個要求

    • 它使父進程去睡眠來等待子進程的結束
    • 當一個子進程調用exit()的時候, 操作系統解鎖父進程, 并且將通過exit()傳遞得到的返回值作為wait調用的一個結果(連同子進程的pid一起), 如果這里沒有子進程存在, wait()立即返回.
    • 當然, 如果這里有為父進程的僵尸等待, wait()立即返回其中一個值(并且解除僵尸狀態).

    具體步驟如下:

    • 進程結束執行之后, 它調用exit() -- 系統調用
    • 這個系統調用:
    • 將這個程序的"結果"作為一個參數
    • 關閉所有打開文件, 連接等等
    • 釋放內存
    • 釋放大部分支持進程的操作系統結構
    • 檢查是否父進程是存活著的, 如果存活, 它保留結果的值直到父進程需要它: 在這種情況里, 進程沒有真正死亡, 但是它進入了僵尸狀態. 如果父進程沒有存活 它釋放所有的數據結構, 這個進程死亡.
    • 清理所有等待的僵尸進程
    • 進程終止是最終的垃圾收集(資源回收)

    注意:

    操作系統根進程(初始進程)會定期掃描僵尸進程, 并代替僵尸進程的父進程對其進行釋放.

    總結

    以上是生活随笔為你收集整理的操作系统进程管理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。