成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux 對進程的描述

系統 Linux
進程是操作系統種調度的實體,對進程擁有資源的描述稱為進程控制塊(PCB, Process Contrl Block)。

[[406262]]

進程是操作系統種調度的實體,對進程擁有資源的描述稱為進程控制塊(PCB, Process Contrl Block)。

通過 task_struct 描述進程

內核里,通過 task_struct 結構體來描述一個進程,稱為進程描述符 (process descriptor),它保存著支撐一個進程正常運行的所有信息。task_struct 結構體內容太多,這里只列出部分成員變量,感興趣的讀者可以去源碼 include/linux/sched.h頭文件查看。

  1. struct task_struct { 
  2.  
  3. #ifdef CONFIG_THREAD_INFO_IN_TASK 
  4.   /* 
  5.    * For reasons of header soup (see current_thread_info()), this 
  6.    * must be the first element of task_struct. 
  7.    */ 
  8.   struct thread_info        thread_info; 
  9. #endif 
  10.   volatile long state; 
  11.   void *stack; 
  12.   ...... 
  13.   struct mm_struct *mm; 
  14.   ...... 
  15.   pid_t pid; 
  16.   ...... 
  17.   struct task_struct *parent; 
  18.   ...... 
  19.   char comm[TASK_COMM_LEN]; 
  20.   ...... 
  21.   struct files_struct *files; 
  22.   ...... 
  23.   struct signal_struct *signal; 

task_struct 中的主要信息分類:

1.標示符:描述本進程的唯一標識符 pid,用來區別其他進程。

2.狀態:任務狀態,退出代碼,退出信號等

3.優先級:相對于其他進程的優先級

4.程序計數器:程序中即將被執行的下一條指令的地址

5.內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊的指針

6.上下文數據:進程執行時處理器的寄存器中的數據

7.I/O狀態信息:包括顯示的I/O請求,分配的進程I/O設備和進程使用的文件列表

8.記賬信息:可能包括處理器時間總和,使用的時鐘總和,時間限制,記帳號等

  • struct thread_info thread_info: 進程被調度執行的信息
  • volatile long state:-1是不運行的,=0是運行狀態,>0是停止狀態。下面是幾個比較重要的進程狀態以及它們之間的轉換流程。

  1. void *stack:指向內核棧的指針,內核通過 dup_task_struct 為每個進程都分配內核棧空間,并記錄在此。
  2. struct mm_struct *mm: 與進程地址空間相關的信息。

  • pid_t pid: 進程標識符
  • char comm[TASK_COMM_LEN]: 進程的名稱
  • struct files_struct *files: 打開的文件表
  • struct signal_struct *signal: 信號處理相關

task_struct, thread_info 和內核棧 sp 的關系

接著看下 thread_info 結構:

  1. struct thread_info { 
  2.         unsigned long           flags;          /* low level flags */ 
  3.         mm_segment_t            addr_limit;     /* address limit */ 
  4. #ifdef CONFIG_ARM64_SW_TTBR0_PAN 
  5.         u64                     ttbr0;          /* saved TTBR0_EL1 */ 
  6. #endif 
  7.         union { 
  8.                 u64             preempt_count;  /* 0 => preemptible, <0 => bug */ 
  9.                 struct { 
  10. #ifdef CONFIG_CPU_BIG_ENDIAN 
  11.                         u32     need_resched; 
  12.                         u32     count
  13. #else 
  14.                         u32     count
  15.                         u32     need_resched; 
  16. #endif 
  17.                 } preempt; 
  18.         }; 
  19. #ifdef CONFIG_SHADOW_CALL_STACK 
  20.         void                    *scs_base; 
  21.         void                    *scs_sp; 
  22. #endif 
  23. }; 

接著再來看下內核棧的定義:

  1. union thread_union { 
  2. #ifndef CONFIG_ARCH_TASK_STRUCT_ON_STACK 
  3.         struct task_struct task; 
  4. #endif 
  5. #ifndef CONFIG_THREAD_INFO_IN_TASK 
  6.         struct thread_info thread_info; 
  7. #endif 
  8.         unsigned long stack[THREAD_SIZE/sizeof(long)]; 
  9. }; 

當 CONFIG_THREAD_INFO_IN_TASK 這個配置打開的時候,則 thread_union 結構中只存在 stask 成員了。

內核在啟動的時候會在 head.S 里通過 __primary_switched 來做內核棧的初始化:

  1. SYM_FUNC_START_LOCAL(__primary_switched) 
  2.         adrp    x4, init_thread_union 
  3.         add     sp, x4, #THREAD_SIZE 
  4.         adr_l   x5, init_task 
  5.         msr     sp_el0, x5                      // Save thread_info 

將 init_thread_union 的地址保存到 x4,然后偏移 THREAD_SIZE 棧大小,用于初始化 sp。將 init_task 進程描述符地址賦值給 x5,并保存到 sp_el0。

下面再看下 init_thread_union 和 init_task 的定義:

  1. #include/linux/sched/task.h 
  2. extern union thread_union init_thread_union; 
  3.  
  4. #init/init_task.c 
  5. struct task_struct init_task 
  6.         __aligned(L1_CACHE_BYTES) 
  7. = { 
  8. #ifdef CONFIG_THREAD_INFO_IN_TASK 
  9.         .thread_info    = INIT_THREAD_INFO(init_task), 
  10.         .stack_refcount = REFCOUNT_INIT(1), 
  11. #endif 
  12. ..... 
  13.  }; 

故這三者的關系可以通過下圖描述:

如何獲取當前進程

內核中經常通過 current 宏來獲得當前進程對應的 struct task_sturct 結構,我們借助 current,結合上面介紹的內容,看下具體的實現。

  1. static __always_inline struct task_struct *get_current(void) 
  2.     unsigned long sp_el0; 
  3.   
  4.     asm ("mrs %0, sp_el0" : "=r" (sp_el0)); 
  5.   
  6.     return (struct task_struct *)sp_el0; 
  7.   
  8. #define current get_current() 

代碼比較簡單,可以看出通過讀取用戶空間棧指針寄存器 sp_el0 的值,然后將此值強轉成 task_struct 結構就可以獲得當前進程。(sp_el0 里存放的是 init_task,即 thread_info 地址,thread_info 又是在 task_sturct 的開始處,從而找到當前進程。)

 

責任編輯:武曉燕 來源: 人人都是極客
相關推薦

2009-12-17 14:43:47

紅旗Linux

2023-04-06 15:22:15

Linux進程系統

2020-02-07 18:16:01

進程線程底層原理

2010-05-26 15:03:51

2010-09-15 09:58:20

2010-07-19 18:04:23

SQL Server鎖

2009-11-13 09:28:35

2009-08-06 15:52:11

C#調用外部進程

2010-04-27 16:18:26

Oracle數據字典

2010-05-28 11:14:39

MySQL全文索引限制

2010-09-08 13:31:24

2010-09-30 16:17:13

2010-09-08 15:10:48

2010-05-26 13:50:15

MySQL備份

2010-07-19 16:17:41

SQL Server聚

2010-09-29 12:52:14

2010-03-29 13:55:26

Oracle Mult

2010-09-26 16:25:17

網絡釣魚成功

2011-03-30 11:28:31

SQL Server聚集索引

2010-08-06 14:52:13

DB2 9.7武器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲毛片在线 | 国产乱码精品一区二区三区五月婷 | 亚洲欧美男人天堂 | 成人午夜精品 | 国产视频二区在线观看 | 久久久久久国产精品 | 久久亚洲天堂 | 亚洲一区二区三区免费观看 | 亚洲中字在线 | 日韩中文一区 | 一区二区三区四区电影视频在线观看 | 在线观看黄视频 | 91视频三区 | 久草网址| 国产一区二区三区在线看 | 91 久久 | 午夜视频精品 | 一区影视 | a毛片视频网站 | 亚洲欧美综合精品久久成人 | 91精品午夜窝窝看片 | 国产欧美一区二区三区日本久久久 | 成人在线视频观看 | 成人欧美一区二区三区黑人孕妇 | 欧美精品日韩精品国产精品 | 国产成人精品福利 | 国产亚洲精品久久久久动 | 久久久www成人免费无遮挡大片 | 亚洲乱码国产乱码精品精的特点 | 国产精品视频免费观看 | 亚洲成人在线网 | 免费激情网站 | 欧美亚洲国产日韩 | 成人午夜免费视频 | 91精品国产91久久综合桃花 | 欧美专区在线视频 | 中文字幕亚洲精品 | 精品一区二区三区av | 81精品国产乱码久久久久久 | 成人夜晚看av | 怡红院怡春院一级毛片 |