吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux的進程

strongerHuang ? 來源:嵌入式Hacker ? 作者:吳偉東 ? 2020-11-29 09:51 ? 次閱讀

目的:

初步了解進程描述符 task_struct。

目錄:

Linux的進程

Linux 的進程描述符

task_struct

內核如何找到 task_struct

task_struct 的分配和初始化

實驗:打印 task_struct / thread_info / kernel mode stack

環境:

Linux-4.14 + ARMv7

1. Linux 的進程

進程的術語是 process,是 Linux 最基礎的抽象,另一個基礎抽象是文件。

最簡單的理解,進程就是執行中 (executing, 不等于running) 的程序。

更準確一點的理解,進程包括執行中的程序以及相關的資源(包括cpu狀態、打開的文件、掛起的信號、tty、內存地址空間等)。

一種簡潔的說法:進程 = n*執行流 + 資源,n>=1。

Linux 進程的特點:

通過系統調用 fork() 創建進程,fork() 會復制現有進程來創建一個全新的進程。

內核里,并不嚴格區分進程和線程。

從內核的角度看,調度單位是線程 (即執行流)。可以把線程看做是進程里的一條執行流,1個進程里可以有1個或者多個線程。

內核里,常把進程稱為 task 或者 thread,這樣描述更準確,因為許多進程就只有1條執行流。

內核通過輕量級進程 (lightweight process) 來支持多線程。1個輕量級進程就對應1個線程,輕量級進程之間可以共享打開的文件、地址空間等資源。

2. Linux 的進程描述符

2.1 task_struct

內核里,通過 task_struct 結構體來描述一個進程,稱為進程描述符 (process descriptor),它保存著支撐一個進程正常運行的所有信息

每一個進程,即便是輕量級進程(即線程),都有1個 task_struct。

sched.h(includelinux) structtask_struct{ structthread_infothread_info; volatilelongstate; void*stack; [...] structmm_struct*mm; [...] pid_tpid; [...] structtask_struct*parent; [...] charcomm[TASK_COMM_LEN]; [...] structfiles_struct*files; [...] structsignal_struct*signal; }

這是一個龐大的結構體,不僅有許多進程相關的基礎字段,還有許多指向其他數據結構的指針。

它包含的字段能完整地描述一個正在執行的程序,包括 cpu 狀態、打開的文件、地址空間、掛起的信號、進程狀態等。

點擊查看大圖

作為初學者,先簡單地了解部分字段就好::

struct thread_info thread_info:進程底層信息,平臺相關,下面會詳細描述。

long state:進程當前的狀態,下面是幾個比較重要的進程狀態以及它們之間的轉換流程。

點擊查看大圖

void *stack:指向進程內核棧,下面會解釋。

struct mm_struct *mm:與進程地址空間相關的信息都保存在一個叫內存描述符 (memory descriptor) 的結構體 (mm_struct) 中。

點擊查看大圖

pid_t pid:進程標識符,本質就是一個數字,是用戶空間引用進程的唯一標識。

struct task_struct *parent:父進程的 task_struct。

char comm[TASK_COMM_LEN]:進程的名稱。

struct files_struct*files:打開的文件表。

struct signal_struct *signal:信號處理相關。

其他字段,等到有需要的時候再回過頭來學習。

2.2 當發生系統調用或者進程切換時,內核如何找到 task_struct ?

對于 ARM 架構,答案是:通過內核棧 (kernel mode stack)。

為什么要有內核棧?

因為內核是可重入的,在內核中會有多條與不同進程相關聯的執行路徑。因此不同的進程處于內核態時,都需要有自己私有的進程內核棧 (process kernel stack)。

當進程從用戶態切換到內核態時,所使用的棧會從用戶棧切換到內核棧。

至于是如何切換的,關鍵詞是系統調用,這不是本文關注的重點,先放一邊,學習內核要懂得恰當的時候忽略細節。

當發生進程切換時,也會切換到目標進程的內核棧。

同上,關鍵詞是硬件上下文切換 (hardware context switch),忽略具體實現。

無論何時,只要進程處于內核態,就會有內核棧可以使用,否則系統就離崩潰不遠了。

ARM 架構的內核棧和 task_struct 的關系如下:

內核棧的長度是 THREAD_SIZE,對于 ARM 架構,一般是 2 個頁框的大小,即 8KB。

內核將一個較小的數據結構 thread_info 放在內核棧的底部,它負責將內核棧和 task_struct 串聯起來。thread_info 是平臺相關的,在 ARM 架構中的定義如下:

//thread_info.h(archarmincludeasm) structthread_info{ unsignedlongflags;/*lowlevelflags*/ intpreempt_count;/*0=>preemptable,<0?=>bug*/ mm_segment_taddr_limit;/*addresslimit*/ structtask_struct*task;/*maintaskstructure*/ [...] structcpu_context_savecpu_context;/*cpucontext*/ [...] };

thread_info 保存了一個進程能被調度執行的最底層信息(low level task data),例如struct cpu_context_save cpu_context 會在進程切換時用來保存/恢復寄存器上下文。

內核通過內核棧的棧指針可以快速地拿到 thread_info:

//thread_info.h(includelinux) staticinlinestructthread_info*current_thread_info(void) { //current_stack_pointer是當前進程內核棧的棧指針 return(structthread_info*) (current_stack_pointer&~(THREAD_SIZE-1)); }

然后通過 thread_info 找到 task_struct:

//current.h(includeasm-generic) #definecurrent(current_thread_info()->task)

內核里通過 current 宏可以獲得當前進程的 task_struct。

2.3 task_struct 的分配和初始化

當上層應用使用 fork() 創建進程時,內核會新建一個 task_struct。

進程的創建是個復雜的工作,可以延伸出無數的細節。這里我們只是簡單地了解一下 task_struct 的分配和部分初始化的流程。

fork() 在內核里的核心流程:

dup_task_struct() 做了什么?

至于設置內核棧里做了什么,涉及到了進程的創建與切換,不在本文的關注范圍內,以后再研究了。

3. 實驗:打印 task_struct / thread_info / kernel mode stack

實驗目的:

梳理 task_struct / thread_info / kernel mode stack 的關系。

實驗代碼:

#include #include #include staticvoidprint_task_info(structtask_struct*task) { printk(KERN_NOTICE"%10s%5dtask_struct(%p)/stack(%p~%p)/thread_info->task(%p)", task->comm, task->pid, task, task->stack, ((unsignedlong*)task->stack)+THREAD_SIZE, task_thread_info(task)->task); } staticint__inittask_init(void) { structtask_struct*task=current; printk(KERN_INFO"taskmoduleinit "); print_task_info(task); do{ task=task->parent; print_task_info(task); }while(task->pid!=0); return0; } module_init(task_init); staticvoid__exittask_exit(void) { printk(KERN_INFO"taskmoduleexit "); } module_exit(task_exit);

運行效果:

taskmoduleinit insmod3123task_struct(edb42580)/stack(ed46c000~ed474000)/thread_info->task(edb42580) bash2393task_struct(eda13e80)/stack(c9dda000~c9de2000)/thread_info->task(eda13e80) sshd2255task_struct(ee5c9f40)/stack(c9d2e000~c9d36000)/thread_info->task(ee5c9f40) sshd543task_struct(ef15f080)/stack(ee554000~ee55c000)/thread_info->task(ef15f080) systemd1task_struct(ef058000)/stack(ef04c000~ef054000)/thread_info->task(ef058000)

在程序里,我們通過 task_struct 找到 stack,然后通過 stack 找到 thread_info,最后又通過 thread_info->task 找到 task_struct。

4. 相關參考

Linux 內核設計與實現 / 第 3.1 章節

深入理解 Linux 內核 / 3

Linux 內核深度解析 / 2.5.1

深入Linux 內核架構 / 2.3

責任編輯:lq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11345

    瀏覽量

    210392
  • 多線程
    +關注

    關注

    0

    文章

    278

    瀏覽量

    20074
  • 進程
    +關注

    關注

    0

    文章

    204

    瀏覽量

    13995

原文標題:Linux 內核 / 進程管理 / 如何描述一個進程?

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    深入解析Linux程序與進程

    什么是程序 一組計算機能識別和執行的指令,用于指導計算機執行特定任務或解決特定問題。程序通常由代碼、數據和資源文件組成,涉及語法、算法和數據結構。為二進制文件 什么是進程 是一個具有獨立功能的程序
    的頭像 發表于 12-18 11:01 ?158次閱讀
    深入解析<b class='flag-5'>Linux</b>程序與<b class='flag-5'>進程</b>

    Linux之CPU調度策略和CPU親和性

    一、調度策略 調度進程 單個 CPU一次只能執行一個進程,雖然 Linux 系統通過使用多任務同時處理多個進程,但當多個進程同時運行在一個C
    的頭像 發表于 12-05 16:38 ?594次閱讀
    <b class='flag-5'>Linux</b>之CPU調度策略和CPU親和性

    程序和進程的區別

    比如: 開發寫的代碼我們稱為程序,那么將開發的代碼運行起來。我們稱為進程
    的頭像 發表于 11-25 16:03 ?493次閱讀
    程序和<b class='flag-5'>進程</b>的區別

    深入Linux進程管理:提升效率與穩定性的關鍵方法

    目錄 Linux進程管理 8.1 IO負載 8.2 實時進程監控 5.1 作業與會話 5.2 作業分類 4.1 ps 4.2pstree 4.3pgrep 4.4pidof 4.5 vmstat
    的頭像 發表于 11-22 11:05 ?362次閱讀
    深入<b class='flag-5'>Linux</b><b class='flag-5'>進程</b>管理:提升效率與穩定性的關鍵方法

    一文搞懂Linux進程的睡眠和喚醒

    ): 進程在等待某個條件滿足(如I/O操作),可以被信號喚醒。 Linux通過內核提供的系統調用來控制進程的睡眠。常用的系統調用有: sleep(): 使進程暫停指定的秒數。 usl
    發表于 11-04 15:15

    Linux網絡基礎知識總結

    同 CPU、內存以及 I/O 一樣,網絡也是 Linux 系統最核心的功能。 網絡是一種把不同計算機或網絡設備連接到一起的技術,它本質上是一種進程間通信方式,特別是跨系統的進程間通信,必須要通過網絡才能進行。
    的頭像 發表于 10-28 10:42 ?298次閱讀
    <b class='flag-5'>Linux</b>網絡基礎知識總結

    Linux lsof命令的基本用法

    linux 系統中,一切皆文件。通過文件不僅僅可以訪問常規數據,還可以訪問網絡連接和硬件。所以 lsof 命令不僅可以查看進程打開的文件、目錄,還可以查看進程監聽的端口等 socket 相關的信息。本文將介紹 lsof 命令
    的頭像 發表于 10-23 11:52 ?423次閱讀
    <b class='flag-5'>Linux</b> lsof命令的基本用法

    Linux用戶身份與進程權限詳解

    在學習 Linux 系統權限相關的主題時,我們首先關注的基本都是文件的 ugo 權限。ugo 權限信息是文件的屬性,它指明了用戶與文件之間的關系。但是真正操作文件的卻是進程,也就是說用戶所擁有的文件
    的頭像 發表于 10-23 11:41 ?427次閱讀
    <b class='flag-5'>Linux</b>用戶身份與<b class='flag-5'>進程</b>權限詳解

    Linux調度器的核心scheduler_tick介紹

    scheduler_tick在Linux內核中扮演著關鍵角色。它不僅負責處理定時器中斷和更新系統時間,還記錄進程的運行時間,并決定是否需要進行任務切換。通過這些功能,scheduler_tick有效保障了系統的時間管理和任務調度,使操作系統能夠高效、準確地管理多個
    的頭像 發表于 08-22 14:54 ?497次閱讀

    深入探討Linux進程調度器

    Linux操作系統作為一個開源且廣泛應用的操作系統,其內核設計包含了許多核心功能,而進程調度器(Scheduler)就是其中一個至關重要的模塊。進程調度器負責決定在任何給定的時刻哪個進程
    的頭像 發表于 08-13 13:36 ?994次閱讀
    深入探討<b class='flag-5'>Linux</b>的<b class='flag-5'>進程</b>調度器

    Linux項目開發,你必須了解Systemd服務!

    1.Systemd簡介Systemd是什么,以前linux系統啟動init機制,由于init一方面對于進程的管理是串行化的,容易出現阻塞情況,另一方面init也僅僅是執行啟動腳本,并不能對服務
    的頭像 發表于 06-18 17:59 ?898次閱讀
    <b class='flag-5'>Linux</b>項目開發,你必須了解Systemd服務!

    鴻蒙開發:【進程模型】

    應用中(同一Bundle名稱)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是運行在同一個獨立進程(主進程)中,如下圖中綠色部分的“Main Process”。
    的頭像 發表于 06-13 09:53 ?332次閱讀
    鴻蒙開發:【<b class='flag-5'>進程</b>模型】

    Linxu進程的延遲與周期調度

    pstree 命令以樹狀結構顯示系統進程的繼承關系。樹狀圖將會以 pid (如果有指定) 或是以 init 為根,如果指定 user,則樹狀結構只顯示該用戶所擁有的進程
    發表于 04-18 11:24 ?211次閱讀

    true studio調試,只顯示匯編進程不顯示C進程的原因?

    true studio 調試,只顯示匯編進程,不顯示C進程的原因?
    發表于 04-18 06:56

    linux下查詢進程占用的內存方法有哪些?

    linux下查詢進程占用的內存方法
    發表于 04-08 06:03
    淘金盈娱乐城| 大发888客户端下载| 威斯汀百家乐的玩法技巧和规则| 百家乐套利| 赢真钱的棋牌游戏| 巴登娱乐城| 真钱百家乐官网送钱| 真人百家乐官网游戏网址| 百家乐官网网络游戏信誉怎么样| 百家乐投注网中国体育| 威尼斯人娱乐城线路lm0| 联众德州扑克| 博彩网百家乐官网中和局| 百家乐金币游戏| 赌博百家乐的玩法技巧和规则| 97玩棋牌游戏中心| 网络百家乐官网免费试玩| 百家乐官网有试玩的吗| 蓝盾百家乐的玩法技巧和规则| 八大胜投注,| 百家乐官网游戏排行榜| 百家乐官网德州| 威尼斯人娱乐城平台打不开| 赌场风云演员表| 百家乐官网赌场凯时娱乐| 真人百家乐园| 元游棋牌游戏下载| 澳门百家乐官网技术| 网络百家乐游戏机怎么破解| 德州扑克书| 百家乐官网赌场凯时娱乐| 百家乐赌场详解| 皇冠博彩| 大世界百家乐官网娱乐网| 百家乐图淑何看| E乐博网址| 女优百家乐官网的玩法技巧和规则 | 赌博百家乐探讨| bet365 app| 百家乐官网博赌场娱乐网规则| 百佬汇百家乐的玩法技巧和规则|