Linux进程描述符task_struct结构体简析
進程是處于執行期的程序以及它所管理的資源(如打開的文件、掛起的信號、進程狀態、地址空間等等)的總稱
Linux內核通過一個被稱為進程描述符的task_struct結構體來管理進程,這個結構體包含了一個進程所需的所有信息。它定義在include/linux/sched.h文件中。
這個結構體中包含了很多的信息,下面就讓我們來一一簡單的看看這些結構體內容,對進程描述符有一個基本的理解。
進程狀態
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
state成員的可能取值如下
/** Task state bitmask. NOTE! These bits are also* encoded in fs/proc/array.c: get_task_state().** We have two separate sets of flags: task->state* is about runnability, while task->exit_state are* about the task exiting. Confusing, but this way* modifying one set can't modify the other one by* mistake.*/#define TASK_RUNNING 0#define TASK_INTERRUPTIBLE 1#define TASK_UNINTERRUPTIBLE 2#define __TASK_STOPPED 4#define __TASK_TRACED 8/* in tsk->exit_state */#define EXIT_DEAD 16#define EXIT_ZOMBIE 32#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)/* in tsk->state again */#define TASK_DEAD 64#define TASK_WAKEKILL 128 /** wake on signals that are deadly **/#define TASK_WAKING 256#define TASK_PARKED 512#define TASK_NOLOAD 1024#define TASK_STATE_MAX 2048/* Convenience macros for the sake of set_task_state */
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED)
上面的這些狀態又分為下面的幾類
5個互斥狀態
state可以是5個互斥狀態中的一種,系統中的進程必須處于5個狀態中的一種。
這個5個狀態的具體描述如下
| 狀態 | 描述 |
|---|---|
| TASK_RUNNING | 表示進程要么正在執行,要么正要準備執行(已經就緒),正在等待cpu時間片的調度 |
| TASK_INTERRUPTIBLE | 進程因為等待一些條件而被掛起(阻塞)而所處的狀態。這些條件主要包括:硬中斷、資源、一些信號……,一旦等待的條件成立,進程就會從該狀態(阻塞)迅速轉化成為就緒狀態TASK_RUNNING |
| TASK_UNINTERRUPTIBLE | 意義與TASK_INTERRUPTIBLE類似,除了不能通過接受一個信號來喚醒以外,對于處于TASK_UNINTERRUPIBLE狀態的進程,哪怕我們傳遞一個信號或者有一個外部中斷都不能喚醒他們。只有它所等待的資源可用的時候,他才會被喚醒。這個標志很少用,但是并不代表沒有任何用處,其實他的作用非常大,特別是對于驅動刺探相關的硬件過程很重要,這個刺探過程不能被一些其他的東西給中斷,否則就會讓進城進入不可預測的狀態 |
| TASK_STOPPED | 進程被停止執行,當進程接收到SIGSTOP、SIGTTIN、SIGTSTP或者SIGTTOU信號之后就會進入該狀態 |
| TASK_TRACED | r表示進程被debugger等進程監視,進程執行被調試程序所停止,當一個進程被另外的進程所監視,每一個信號都會讓進城進入該狀態 |
5個互斥狀態
兩個附加的進程狀態既可以被添加到state域中,又可以被添加到exit_state域中。只有當進程終止的時候,才會達到這兩種狀態.
/* task state */
int exit_state;
int exit_code, exit_signal;
| 狀態 | 描述 |
|---|---|
| EXIT_ZOMBIE | 進程的執行被終止,但是其父進程還沒有使用wait()等系統調用來獲知它的終止信息,此時進程成為僵尸進程 |
| EXIT_DEAD | 進程的最終狀態 |
新增睡眠狀態
進程狀態 TASK_UNINTERRUPTIBLE 和 TASK_INTERRUPTIBLE 都是睡眠狀態
進程標識符(PID)
pid_t pid;
pid_t tgid;
通過查看源代碼我們發現pid_t的類型就是一個整型,每個進程在創建的時候都會返回一個進程標識符(PID),就好像一個身份證號碼一樣,用來唯一標識一個進程。
在CONFIG_BASE_SMALL配置為0的情況下,PID的取值范圍是0到32767,即系統中的進程數最大為32768個。
進程內核棧
void *stack;
這里關于進程內核棧,專門寫一篇博客,可以看過來
進程內核棧
進程標記
unsigned int flags; /* per process flags, defined below */
反應進程狀態的信息,但不是運行狀態,用于內核識別進程當前的狀態,以備下一步操作
flags成員的可能取值如下,這些宏以PF(ProcessFlag)開頭
例如
PF_FORKNOEXEC 進程剛創建,但還沒執行。
PF_SUPERPRIV 超級用戶特權。
PF_DUMPCORE dumped core。
PF_SIGNALED 進程被信號(signal)殺出。
PF_EXITING 進程開始關閉。
表示進程親屬關系的成員
/** pointers to (original) parent process, youngest child, younger sibling,* older sibling, respectively. (p->father can be replaced with* p->real_parent->pid)*/
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/** children/sibling forms the list of my natural children*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
struct task_struct *group_leader; /* threadgroup leader */
在Linux系統中,所有進程之間都有著直接或間接地聯系,每個進程都有其父進程,也可能有零個或多個子進程。擁有同一父進程的所有進程具有兄弟關系。
| 字段 | 描述 |
|---|---|
| real_parent | 指向其父進程,如果創建它的父進程不再存在,則指向PID為1的init進程 |
| parent | 指向其父進程,當它終止時,必須向它的父進程發送信號。它的值通常與real_parent相同 |
| children | 表示鏈表的頭部,鏈表中的所有元素都是它的子進程 |
| sibling | 用于把當前進程插入到兄弟鏈表中 |
| group_leader | 指向其所在進程組的領頭進程 |
ptrace系統調用
ptrace 提供了一種父進程可以控制子進程運行,并可以檢查和改變它的核心image
Performance Event
Performance Event是一款隨 Linux 內核代碼一同發布和維護的性能診斷工具。這些成員用于幫助PerformanceEvent分析進程的性能問題
進程調度
優先級
用來描述進程的調度方式,調度策略
進程地址空間
內核除了管理本身的內存外,還必須管理用戶空間中進程的內存,我們稱這個內存為進程地址空間,也就是系統中每個用戶空間進程所看到的內存
還有其他的一些
判斷標志
時間
信號處理
其他
總結
以上是生活随笔為你收集整理的Linux进程描述符task_struct结构体简析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 元气骑士唱片怎么用?
- 下一篇: 电影院一共有22排座位,第一排有24个座