操作系統學習筆記4 | CPU管理 && 多進程圖像

来源:https://www.cnblogs.com/Roboduster/archive/2022/08/20/16607037.html
-Advertisement-
Play Games

操作系統的核心功能就是管理電腦硬體,而CPU就是電腦中最核心的硬體。操作系統通過多進程圖像實現對CPU的管理。所以多進程圖像是操作系統的核心圖像。 ...


操作系統的核心功能就是管理電腦硬體,而CPU就是電腦中最核心的硬體。而通過學習筆記3的簡史回顧,操作系統通過多進程圖像實現對CPU的管理。所以多進程圖像是操作系統的核心圖像


參考資料:


1. 從使用CPU開始直觀理解CPU管理

要想管理CPU,就要知道如何使用CPU。

CPU的工作原理已經很熟悉:

  • 取指執行
    • 程式存放在記憶體中,每段指令對應一個地址
    • CPU發出取指命令,將想去地址通過地址匯流排傳到PC
    • 記憶體根據地址取出對應地址的指令
    • 從匯流排傳回,CPU解釋執行

所以,管理CPU最直觀的方法就是,設置PC的初值,CPU就能按照規則依次執行下去。

這一點在計組實驗的前四周手搖實驗室設備進行指令執行,也可以有類似的印象。

這樣做有什麼問題?

  • 來看下麵一段程式

    int main(int argc,char* argv[]){
        int i,to,*fp,sum=0;
        to = atoi(agv[1]);
        for(i = 1; i <=to; i++){
            sum = sum + i;
            fprintf(fp,"%d",sum);
        }
    }
    
  • 如果要讓CPU工作,就是要讓PC指向這段程式的起始地址。

  • 但是!程式和程式之間是不一樣的。例如將fprintf()替換為其他計算語句

    fprintf()是一個IO指令,而替換為計算語句則成為計算指令

  • 替換前後的運行時長進行比較,則前者:後者≈106:1

    說明,IO特別慢

  • 而假設我們遇到一種程式,有106個計算指令,然後一條IO指令,如果還是按照上面所說的設置PC初值,讓其自動執行,那麼對於CPU來說,其忙碌的計算指令只占到了總時長的一半(另一半在等待IO),利用率不高。

    而如果IO語句再多一點,CPU利用率就更低了。

怎麼辦?

2. CPU管理的核心:併發

  • 舉一個燒水的例子,首先往燒水壺裡倒水,然後放在插座上,然後就可以去做別的事情了,等燒水壺響了,這就是中斷,這時我們就可以來用燒水壺裡的熱水了,燒水的過程就類似IO

  • 所以解決方案為:多道程式交替執行,一個CPU上交替執行多個程式,即併發

    這樣一道程式執行到像IO這樣慢的步驟時,CPU切換到另一個程式進行,而另一個程式進入等待後,再切換回來。

image

可見,上圖兩個程式A、B充分利用了CPU的計算資源,總時長從80降到了45.

註意兩個名詞:並行和併發:

並行多人同時工作,併發一個人交替工作。

並且這裡一個隱含條件是切換程式的開銷要小於運行程式的開銷。

如何實現併發呢?

  • 即控制 PC 進行切換

  • 適當的時候修改PC,使得PC指向另一個程式的指令,但是只修改PC會有問題

  • 例如下圖左右兩個程式,當PC按照邏輯切換回地址53繼續程式1的執行,那麼ax和bx寄存器應當存儲什麼值?

    很顯然,如果要繼續程式1,當然應當為1 和 1,而不是 10 和 10.

    所以當程式切換時,除了切換PC,還要切換很多內容

  • 我們需要記錄 切換前的上下文,保護現場。

  • 每個程式有一個存放信息的結構:PCB,process control block,進程式控制制塊。

    就像我們正在看書,突然被人叫走做別的事,我們就應當停下來,記錄當前頁碼以及故事情節,然後離開,這樣回來後才能繼續閱讀。

    image

  • 這樣,我們實際運行過程中的程式,就跟我們單純彙編得到的代碼不一樣了。即運行程式和靜態程式不一樣。

    不同之處簡單來說就在於需要PCB來記錄程式運行起來的樣子。

    而程式 + 所有這些不一樣 ---> 進程

  • 如何描述這種不同呢?

!進程! 這個概念就用來刻畫運行中的程式。比如上圖中的程式1 和程式2,就是兩個進程

也即進行中的程式,名字其實很形象。

  • 進程有開始、結束,程式沒有;
  • 進程會走走停停,是動態的,有狀態的,而程式沒有;
  • 進程需要記錄ax,bx..... 程式不用;

3. 簡單總結1

  • 到這裡,我們進程描述CPU的管理:

    • 使用CPU:啟動一個進程,讓CPU去執行這個進程;

    • 更高效的使用CPU:啟動多個進程,讓CPU去執行多個進程;

    • 跑多個程式/進程的樣子,就是CPU管理的核心樣子。

      這就是多進程圖像。

4. 多進程圖像

前文講到,為了讓CPU更好的工作,我們需要讓CPU執行多進程,而這個過程如何表徵呢?

  • 對於用戶而言
    • 就是一個個 PID 進程號;
    • 可供用戶查看各進程運行情況;
  • 對於下層操作系統而言
    • 負責管理 各個進程;具體為記錄情況、按照合理的次序推進;
    • 分配資源、進行調度;

多進程圖像從開機一直存在到關機結束。

4.1 開機到關機過程中的多進程圖像

  • 系統啟動時,最後啟動的 main.c 中最後執行了fork()

    if(!fork()){init();}
    // fork,啟動進程的介面
    

    代碼意思是:啟動一個進程,執行init() ,即執行 shell,接下來就能再 shell 里操作,這就是電腦提供給用戶使用的界面(初代版本)。

    可以理解為,操作系統要讓用戶使用電腦,需要創建一個初始化的進程。

    補充1:

    shell是一個子進程,父進程(main函數)因為成功創建子進程,所以fork()>0 不進init 而子進程fork()==0 進入init,啟動shell

    補充2:

    fork()函數返回值是0或1, 返回0代表當前進程是新fork出來的子進程, 非零(也就是為1)代表當前進程為父進程, if條件里的就是父進程的邏輯,一直等待用戶輸入命令, 然後執行, 一直重覆進行

  • shell 再根據用戶輸入啟動其他進程,執行用戶的命令也是在創建進程;

    // shell 的核心代碼
    int main(){
        while(1){
            scanf("%s",cmd);
            if(!fork()){
                exec(cmd);
                wait();
            }
        }
    }
    

    image

  • 此後,電腦每執行一個任務,就開啟一個進程。

4.2 查看當前進程情況 | 任務管理器

在 win10 以上版本中,Ctrl + Shift + Esc 就可看到任務管理器。

  • 其中Explorer是整個Windows的文件系統,如果關掉整個進程,就只能看見背景了。
  • 如果感覺電腦特別慢,就可以打開任務管理器,查看占用CPU資源比例大的進程。
  • 操作系統就是通過管理進程,來管理用戶對電腦的使用。

4.3 操作系統如何實現多進程圖像

為了實現多進程圖像,操作系統都應該解決哪些問題?

  1. 多進程如何組織?
  2. 多進程如何切換?
  3. 多進程交替時,如何相互影響?
  1. 多進程如何組織?也即多進程如何存放?

    • 操作系統感知進程依賴於PCB,組織和存放進程也靠PCB,通過PCB形成一些數據結構(隊列),來組織多進程;如下圖:

      PCB在這裡相當於結構體,組成數據結構的基本單位。

    • 組織好多進程,才能合理推進多進程。

      image.png

  2. 如何推進多進程?

    • 一個進程正在執行

    • 另一些進程在排隊(就緒隊列)等待執行

    • 還有一些在等待觸發事件,即使排到也不能調度執行

      比如上圖中的第三列PCB,在等待磁碟操作。

      PCB是用來記錄進程信息的數據結構

    • 總結:多進程對應的PCB分別放在不同的地方,執行不同的處理。

    • 把進程通過狀態區分開來,通過操作系統對進程狀態的轉移控制,多進程就向前推進了。

      image.png

  3. 多進程如何交替/切換?

    這部分後續會詳細講解,下麵還是簡略的過程。

    • 情境:一個進程啟動磁碟讀寫,等待時進行切換。

      下圖展示了關鍵代碼,代碼註釋見圖中紅色字體;

    • schedule()函數是重點,即調度函數;

    • 下圖中的getNext從就緒隊列中挑出下一個需要占用CPU的進程;

      選擇哪一個進程合適,即進程調度問題,也會用一講來講解。

    • switch_to就是用 PCB 進行進程上下文的切換pCurpNew分別指當前進程的 PCB 和調度得到的下一個進程的 PCB ,即進行執行現場的更替。

      交替的三部分:

      • 隊列操作+調度+切換
    • image.png

  4. 進程如何調度?

    • 這裡先講兩個基礎調度演算法。
      • FIFO,First In First Out.
        • 顯然是比較公平的策略,但是沒有考慮進程執行的任務輕重緩急;
      • Priority.
        • 對進程賦予優先順序,但如何賦予也是個問題。
  5. 切換進程

    • 調度找到下一個占用CPU的進程後,就要進行切換;

      這個過程需要精細控制,所以需要 彙編代碼,下圖為偽代碼;

    • 做的事情也不難想象,先把將要停下的進程信息保存到PCB1中(將當前CPU的各種信息(寄存器等)保存到pCur中),

      再從將要進行的進程的PCB2中取出信息賦到對應寄存器/位置(將pNew中的寄存器等信息恢復到CPU中

    • image.png
  6. 多進程交替時,如何相互影響?

    互斥、鎖的概念。

    • 多進程看似不打照面,但實際上它們同時在一個記憶體來存放。

      多個進程交替執行會相互影響,包括正面的多進程合作,負面的記憶體地址衝突等等

      image.png

    • 比如,進程1中,修改了某個地址的值,而這個地址,正好時進程2 包含的地址,這時就會引起進程2崩潰。

    • 如何解決進程間矛盾?

      限制對進程2地址的讀寫。即:!記憶體映射!

      其實涉及記憶體管理了,可見記憶體管理也服務於CPU管理的多進程圖像。

      通過一個映射表,將真實物理地址轉化為虛擬存儲地址

      image.png

      兩個進程的100記憶體地址,是虛擬邏輯地址,會映射到不同的物理記憶體;下圖中展示了兩個進程的100地址分別映射到了物理地址780和1260

      image.png

    • 還有一些時候,進程之間需要進行合作,如何進行進程間合作?

    • 舉例1(淺顯):

      • 不同的應用程式提交列印任務,列印任務會被放到“待列印文件隊列”
      • 列印進程會從“待列印文件隊列”中一個接一個的取出列印任務,控制印表機列印
      • 如果對存入列印進程的任務不進行管理,如任務1沒放完,任務2就開始放,後面切換時就會出現順序執行所不會遇到的亂序問題。
    • 舉例2(稍深):生產者-消費者實例

      • image.png

      • 生產者和消費者通過共用數據buffer[]進行合作

      • 如果緩衝區滿了,就不應該再放了,

        counter記錄,如果==buffer_size,說明滿了,死迴圈;沒滿則counter++

        如果要避免緩衝區滿而還向里放的情況,counter 這個信號量必須要保持正確(我突然感覺這是工程代碼調試的一個關鍵)

      • 如果多個進程都在記憶體中交替執行,counter可能就會出錯。

        下麵是個具體的例子:

        初始counter=5,生產者執行counter++,消費者執行counter--,在寄存器層面將會是:

        // 生產者P
        register = counter;
        register = register+1;
        counter = register;
        
        // 消費者C
        register = counter;
        register = register -1;
        counter = register;
        

        當生產者的程式執行到中間切換到消費者,可能的代碼序列如右上角所示,counter 直接亂了。後續合作就也會亂套。

        image.png

      • 解決合作問題(合作各方的合理推進順序)的核心在於 !進程同步!

        給 counter 上鎖,即寫 counter 時阻斷其他進程訪問 counter.

        image.png

5. 簡單總結2

  • 理解CPU管理的基本想法

  • 直觀感受了操作系統的多進程

  • 具體瞭解了多進程圖像,探討了操作系統如何實現多進程圖像。

    補充操作系統 多進程圖像的發展:

    批處理(順序)--->多道程式處理---->分時系統

  • 這時多進程圖像的大致輪廓,後續會一一展開:

image.png


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 兄弟們,現在短視頻主播好看的妹子太多了,有時候遇到自己喜歡的,雖然點了贊或者收藏了,但是萬一主播把視頻隱藏下架了呢? 所以今天咱們就用Python來把這些好看的視頻統統保存下來… 涉及知識點 1、動態數據抓包演示 2、json數據解析方法 3、視頻數據保存 環境介紹 python 3.6 pycha ...
  • 實現延時任務有很多的方法,網上關於延時任務的實現的文章已經不少了。比如:實現延時任務的10種方法等等。但是這些文章基本上都是將方法大概的列舉一下,給出部分示例代碼,對於有經驗的老程式員可能一看就知道該怎麼去把它實現完整,但是對於初學者來說不夠友好。所以,我打算寫一個系列的文章,詳細的給出每種延時任務 ...
  • 1.概述 前面三篇介紹了處理Java虛擬機記憶體問題的知識與工具,在處理實際項目的問題 時,除了知識與工具外,經驗也是一個很重要的因素。因此本章將與讀者分享幾個比較 有代表性的實際案例。考慮到虛擬機故障處理和調優主要面向各類服務端應用,而大部 分Java程式員較少有機會直接接觸生產環境的伺服器,因此本 ...
  • CoreShop商城 特色:.net第一國產電商項目,影響力最大 核心商城系統(CoreShop) 是基於 Asp.Net 5.0、Uni-App開發、 支持可視化佈局的小程式商城系統; 前後端分離,支持分散式部署,跨平臺運行;擁有分銷、代理、團購秒殺、 接龍、拼團、直播、優惠券、自定義表單等眾多營 ...
  • 首先先打開我們的Visual Studio 然後點擊[擴展] [管理擴展] 然後搜索[Claudia],點擊[下載]按鈕 稍等一下 這時候會提示我們重新啟動 重新啟動後會這樣,稍等一下 然後點擊[Modify] 然後點擊[End Tasks] 這時VS應該會關閉,並顯示更新配置 一千年後,終於完成了 ...
  • 通常情況下在插件中取Entity中的欄位值是通過強轉或者GetAttributeValue方式,但在實際插件代碼中,去判斷Moeny類型時,做一些直接的計算想一行代碼設置值,最好還是先判斷一下entity中有沒有這個欄位,Entity實體通過查詢返回或者插件的當前操作實體都是只返回有值的欄位,沒有值... ...
  • TAP 是基於任務的非同步模式,在 .NET Framework 4 中引入。TAP取代了 APM 和EAP,是推薦的非同步編程模式。 async / await async 和 await 是為非同步編程提供的語法糖,方便我們快捷編寫非同步代碼。關鍵字 async 作用僅僅是為了能夠使用 await 關鍵 ...
  • Dynaimc CRM查找欄位自定義過濾視圖:Xrm.Page.getControl(arg).addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, isDefault) 實戰筆記 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...