高級操作系統——進程管理

来源:https://www.cnblogs.com/ppbb/archive/2020/03/18/12494794.html
-Advertisement-
Play Games

一、進程描述符 進程式控制制塊PCB:是OS控制進程運行用的數據結構,是一個task_struct結構體。 PCB包括:進程標識信息(進程標識符PID等)、執行現場信息(CPU現場,進程切換時需要保存現場信息)、進程映像信息(進程地址空間,即進程在運行時代碼、數據、棧放在什麼位置,方便OS對地址空間進行 ...


一、進程描述符

進程式控制制塊PCB:是OS控制進程運行用的數據結構,是一個task_struct結構體。

PCB包括:進程標識信息(進程標識符PID等)、執行現場信息(CPU現場,進程切換時需要保存現場信息)、進程映像信息(進程地址空間,即進程在運行時代碼、數據、棧放在什麼位置,方便OS對地址空間進行管理)(現場與地址空間比較重要)、進程資源信息、信號信息。

對PCB,說其中幾個重要的欄位:

mm_struct:有一個成員mm,標明瞭進程的地址空間;

thread:記錄了進程的現場,最後一個欄位;

thread_info在4.4.6版本中改成了stack,包括內核棧(即進程進入內核工作時需要的棧和用戶棧是分開的)和一些需要快速訪問的數據。

 

 

在4.4.6版本中,stack占用了兩個頁面,即8k,大部分是放內核棧的,低端約10k存放快速訪問的信息。CPU若想訪問當前進程的快速訪問數據的話,只需要拿到當前的棧指針,即ESP寄存器的值,可以推算出數據所在的位置來,因此在查找他的地址的時候,訪問速度可以很快。這部分數據可以看作是進程描述符的一部分,在空間上不是連續的,但相互之間有指針,可以相互找得到。

 

 

進程狀態轉換圖,可自行搜索。

在4.4.6中,增加了被跟蹤和僵死撤銷狀態。

進程描述符是管理進程的重要數據結構,故他的組織方式非常重要。0號進程的描述符是由init_task這個變數所存儲的。從他出發,所有進程描述符構成了雙向鏈表。task_struct中包含一個成員,叫tasts,tasks類型是list_head類型,tasts本身是嵌入在進程描述符裡面的,知道tasks的地址,只要送減去620就能得到進程描述符的首地址。在Linux中有很多這樣的技巧,即通過嵌入的地址,反推結構體的地址,進而找到結構體的其他成員。

 

 

進程與線程關係

多個線程構成線程組,共用記憶體,不共用棧。

一個會話對應一個終端,在終端中敲一個命令相當於創建了一個進程組來執行。

下麵進行演示,建立一個文件命名為0.gdb,文件內容如下,直接運行

1 target remote localhost:1234
2 dir ~/aos/lab/busybox
3 add-symbol-file ~/aos/lab/busybox/busybox_unstripped 0x8048400
4 display $lx_current().pid
5 display $lx_current().comm
6 b start_kernel
7 b ls_main
8 c

 

 

執行含有下列代碼的文件

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <pthread.h>
 4 
 5 void loop(){
 6   while(1);
 7 }
 8 
 9 void *p1(){
10   printf("thread-1 starting\n");
11   loop();
12 }
13 
14 void *p2(){
15   printf("thread-2 starting\n");
16   loop();
17 }
18 
19 void main(){
20   int pid1, pid2;
21   pthread_t t1,t2;
22   void *thread_result;
23 
24   printf("main starting\n");
25 
26   if (!(pid1 = fork())){
27     printf("child-1 starting\n");
28     loop();
29     exit(0);
30   }
31 
32   if (!(pid2 = fork())){
33     printf("child-2 starting\n");
34     loop();
35     exit(0);
36   }
37 
38   pthread_create(&t1, NULL, p1, NULL);
39   pthread_create(&t2, NULL, p2, NULL);
40   
41   pthread_join(t1, &thread_result);
42   pthread_join(t2, &thread_result);
43 
44   int status;
45   waitpid(pid1, &status, 0);
46   waitpid(pid2, &status, 0);
47   printf("main exiting\n");
48   exit(0);
49 }

 可以看到do-fork可執行文件創建了三個進程,976、977、978

 

 

 

979、980是新創建的兩個線程

 

 再執行一次,可以看到後臺運行了兩個

 

 新創建的三個進程是剛創建的

 

 fg %+序號將指定的進程放到前臺,ctrl+z放到後臺

 

 

用以下三條命令依次查看線程組、進程組和會話的leader

命令的意思是根據進程的描述符,找到線程組leader的描述符,裡面對應的欄位就是要顯示的ID

p $lx_task_by_pid(977).group_leader->pids[0].pid->numbers.nr
p $lx_task_by_pid(977).group_leader->pids[1].pid->numbers.nr
p $lx_task_by_pid(977).group_leader->pids[2].pid->numbers.nr

987和988是984創建的,他們處於同一個線程組,leader是976

 

二、進程調度演算法

每個進程屬於某一個調度器類,每個調度器類都有一個進程隊列,不同的隊列有不同的調度演算法。

先調度硬實時的,軟實時次之,普通進程最後。

普通進程使用CFS(完全公平)調度演算法:

虛擬時鐘,調度器總是選時鐘最小的那個進程來執行。

優先順序高的進程時鐘增長得慢。

所有可運行的進程被放在一個紅黑樹中。

 

下麵進行演示:

再次運行0.gdb,在終端輸入ls,使其被捕獲

 

 

 

建立文件demo-2-2.gdb,內容如下

 1 break __schedule//進程調度的時候執行這個函數
 2 
 3 break __switch_to//調度時如果切換進程就會調用這個函數
 4   commands
 5     printf "next_p->pid: %d\n", next_p->pid
 6     printf "next_p->se.vruntime: "
 7     print  next_p->se.vruntime
 8   end
 9 
10 break enqueue_task_fair//如果有新進程要進入到CFS隊列時,執行這個函數
11   commands
12     printf "p->pid: %d\n", p->pid
13     printf "p->se.vruntime: "
14     print  p->se.vruntime
15   end
16 
17 display   $lx_current().state//顯示當前進程的狀態
18 display   $lx_current().se.vruntime
19 display   $lx_per_cpu("runqueues").nr_running//CPU裡面有多少個進程在運行
20 
21 display ((struct sched_entity *)((void *)$lx_per_cpu("runqueues").cfs.rb_leftmost - 0x8))->vruntime//CFS隊列里最左邊的節點,即虛擬時鐘最小的信息
22 display ((struct task_struct *)((void *)$lx_per_cpu("runqueues").cfs.rb_leftmost - 0x4c))->pid

 

 

  由上圖可以看到,當前正在運行的是975號進程,當前的虛擬時鐘可以從runtime那裡看到,state=0表示其當前的狀態是就緒的或正在運行,樹最左邊目前還沒有進程。由於enqueue_task_fair函數的作用是往進程隊列裡面加入新進程,現在已經有一個,可以看到,要加的是7號進程,下麵一行的虛擬時鐘是個負值,現在還暫時看不到,繼續執行。

 

 可以看到7號進程的虛擬時鐘小於975號的,下次如果要調度,應該選7號。即將創建的是3號進程。

 

 由上圖,975號進程的虛擬時鐘增加了,在這兩個斷點時間,存在中斷,這才導致了時鐘的增加。運行有一定的隨機性,虛擬機在虛擬的時候有一定的隨機性。繼續

 

 運行了切換函數,下一步要切換7號進程。繼續

 

 7號時鐘的進程的時鐘比之前也增加了,需要註意當前正在運行的進程不放在樹裡面,但放在了隊列裡面,隊列裡面進程就是樹裡面的進程加當前進程。繼續若幹次

 

 下一步要創建的是4號進程。

 

除了普通進程有隊列之外,其他的硬實時和軟實時都有各自的隊列。

紅黑樹的某個節點可以是另外一個樹,共用一個時鐘。

 

三、進程調度的時機

內核程式的入口,系統調用總控函數,異常處理函數,中斷處理函數、內核線程主函數,用bt查看棧頂層,根據函數的種類來確定是哪種內核調用。


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

-Advertisement-
Play Games
更多相關文章
  • ChangeToken這個東西好像已經不止看到它一次兩次了,在Microsoft.Extensions.FileProviders包裡面也有發現它的身影。迷惑了很久之後,今天總算可以找個機會來扒一扒它,看看它到底是一個什麼東西。其實,從MSDN裡面的第一句描述以及這個類的命名,咱們還是可以讀懂它的大... ...
  • Polly每次重試執行不同的操作 前言 最近在寫WG(用的 .net core 3.1 + wpf + abp vnext),程式里大量用到了重試機制選用的是Polly組件(只知道這個...)。 遇到的問題 在當前屏幕下根據NPC名稱查找NPC的坐標,但自己的人物可能會擋住NPC,導致識別不到 需求 ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; n ...
  • 項目是ASP.NET MVC,在重構時頁面時,幾部頁面相同的html代碼,被抽至部分視圖Partial View中去了。但是ASP.NET MVC中,又使用了angularjs。所以部分視圖中的Controller相對於angularjs來說,就成了子控制器Controller。 現在的問題是,在視 ...
  • .NET 5 Preview 1 發佈 去年年底,我們發佈了.NET Core 3.0和3.1.這些版本添加了桌面應用程式模型Windows Forms(WinForms)和WPF,ASP.NET Blazor用於構建SPA應用程式和用於構建分散式應用和服務的gRPC模板、用於與gRPC對話豐富的客 ...
  • At the end of last year, we shipped .NET Core 3.0 and 3.1. These versions added the desktop app models Windows Forms (WinForms) and WPF, ASP.NET Blazo ...
  • 1. 死鎖問題出現 2. 死鎖的成因 3. 死鎖的4個必要條件 4. 死鎖處理方法 1. 死鎖預防 2. 死鎖避免 判斷這次請求是否會引起死鎖? 演算法實現 死鎖避免之銀行家演算法實例 請求出現時: 首先假裝分配,然後調用銀行家演算法 3. 死鎖檢測+恢復: 發現問題再處理 例題: 4. 死鎖忽略 ...
  • 8. gitlab相關介紹 8.1 gitlab優勢 社區版本,自己可以在公司搭建環境 維護人員多,版本更新塊 易用性強,上手快 集成CI(持續集成) 集成CD(持續發佈) 8.2 持續集成 8.2.1 持續集成的優勢 快速發現錯誤。每完成一點更新,就集成到主幹,可以快速發現錯誤,定位錯誤也比較容易 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...