加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 內(nèi)核通過 task_struct 描述進程
    •  
    • task_struct 的分配和初始化
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

Linux 內(nèi)核進程管理之基礎(chǔ)

2021/04/15
286
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

沒有廢話,內(nèi)存管理暫時告一段落,正式進入進程管理的內(nèi)容。

內(nèi)核通過 task_struct 描述進程

用命令 pstree 可以讓內(nèi)核以樹形的結(jié)構(gòu)把進程之間的關(guān)系列出來,如下圖:

這是進程在內(nèi)核中的結(jié)構(gòu)形式,那么內(nèi)核是如何來以樹形結(jié)構(gòu)管理描述這些進程的呢?用來描述進程的數(shù)據(jù)結(jié)構(gòu),可以理解為進程的屬性。比如進程的狀態(tài)、進程的標(biāo)識(PID)等,都被封裝在了進程描述符 task_struct 這個數(shù)據(jù)結(jié)構(gòu)中。

struct task_struct {
  ......
 /* -1 unrunnable, 0 runnable, >0 stopped: */
 //任務(wù)狀態(tài)。<0是不運行狀態(tài),=0是運行狀態(tài),>0是停止?fàn)顟B(tài)。
 volatile long   state;
 ......
 //指向內(nèi)核棧的指針
 void    *stack;
 ......
 /*進程的調(diào)度策略,有6種。
 *限期進程調(diào)度策略:SCHED_DEADLINE。
 *實時進程調(diào)度策略:SCHED_FIFO,SCHED_RR。
 *普通進程調(diào)度策略:SCHED_NORMAL,SCHED_BATCH,SCHED_IDLE。
 */
 unsigned int   policy;
 ......
 //進程內(nèi)存管理信息
 struct mm_struct  *mm;
 struct mm_struct  *active_mm;
 ......
 //進程標(biāo)識符,用來代表一個進程
 pid_t pid;    
 ......
 //線程鏈表
 struct list_head  thread_group;
 struct list_head  thread_node;

 struct completion  *vfork_done;
 ......
 /* Filesystem information: */
 //文件系統(tǒng)信息
 struct fs_struct  *fs;

 /* Open file information: */
 //打開文件信息
 struct files_struct  *files;
 ......
 /* CPU-specific state of this task: */
 //進程的CPU狀態(tài),切換時,要保存到停止進程的task_struct中
 struct thread_struct  thread;
 ......
};

內(nèi)核就是通過list_head鏈表把各個進程關(guān)系以樹形結(jié)構(gòu)管理起來的。

task_struct 結(jié)構(gòu)體內(nèi)容太多,這里只列出部分成員變量,感興趣的讀者可以去源碼 include/linux/sched.h頭文件查看。

task_struct 中的主要信息分類:

  1. 標(biāo)示符:描述本進程的唯一標(biāo)識符 pid,用來區(qū)別其他進程。狀態(tài):任務(wù)狀態(tài),退出代碼,退出信號等優(yōu)先級:相對于其他進程的優(yōu)先級程序計數(shù)器:程序中即將被執(zhí)行的下一條指令的地址內(nèi)存指針:包括程序代碼和進程相關(guān)數(shù)據(jù)的指針,還有和其他進程共享的內(nèi)存塊的指針上下文數(shù)據(jù):進程執(zhí)行時處理器寄存器中的數(shù)據(jù)I/O狀態(tài)信息:包括顯示的I/O請求,分配的進程I/O設(shè)備和進程使用的文件列表記賬信息:可能包括處理器時間總和,使用的時鐘總和,時間限制,記帳號等

 

ARM64不用通過struct thread_info thread_info獲取當(dāng)前task_struct

static __always_inline struct task_struct *get_current(void)
{
        unsigned long sp_el0;

        asm ("mrs %0, sp_el0" : "=r" (sp_el0));

        return (struct task_struct *)sp_el0;
}

#define current get_current()

可以看出 sp_el0 直接作為 task_struct 返回了。對于ARM64平臺,記錄當(dāng)前進程的task_struct地址是利用sp0_el1寄存器,當(dāng)內(nèi)核執(zhí)行進程切換時會把當(dāng)前要運行的進程task_struct地址記錄到該寄存器中。因此我們current查找task_struct時也是很簡單了,不再用通過sp和thread_info去定位了。

volatile long   state

-1是不運行的,=0是運行狀態(tài),>0是停止?fàn)顟B(tài)

 

Linux中的 ready 和 running 對應(yīng)的都是TASK_RUNNING標(biāo)志位,ready 表示進程正處在隊列中,尚未被調(diào)度;running 則表示進程正在CPU上運行;

 
void    *stack

指向內(nèi)核棧的指針,內(nèi)核通過 dup_task_struct 為每個進程都分配內(nèi)核??臻g,并記錄在此。

 

struct mm_struct *mm

與進程地址空間相關(guān)的信息。

 

task_struct 的分配和初始化

圖中可知,上層應(yīng)用通過各種方式創(chuàng)建進程時,最終都會通過 _do_fork 新建一個 task_struct。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

針對嵌入式人工智能,物聯(lián)網(wǎng)等專業(yè)技術(shù)分享和交流平臺,內(nèi)容涉及arm,linux,android等各方面。