首页 > Linux进程描述符task_struct结构体简析

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_TRACEDr表示进程被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分析进程的性能问题


进程调度

优先级

用来描述进程的调度方式,调度策略


进程地址空间

内核除了管理本身的内存外,还必须管理用户空间中进程的内存,我们称这个内存为进程地址空间,也就是系统中每个用户空间进程所看到的内存

还有其他的一些

判断标志


时间


信号处理


其他

更多相关:

  • 在我们面试过程中,面试官经常会问到这么一个问题,那就是从在浏览器地址栏中输入URL到页面显示,浏览器到底发生了什么?这个问题看起来是老生常谈,但是这个问题回答的好坏,确实可以很好的反映出面试者知识的广度和深度。本文从浏览器角度来告诉你,URL后输入后按回车,浏览器内部究竟发生了什么,读完本文后,你将了解到:浏览器内有哪些进程,这些...

  • 进程与线程进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1]。比如,打开一个word文件就是启动了一个word进程。线程(thread)是进程内的子任务。比如word中可以进行编辑、拼写检查和打印等子任务。我们目前的操作系统都是多任务的操作系统,多任务的实现方式[2]:多进程多线程多进程 + 多线程多进程:...

  • 运行cmd netstat -aon|findstr 80 然后 taskkill -f -pid 32428(这个就是pid进程编号) 回车   进程死翘翘了~ 去愉快玩耍吧~哦对了 别忘记一健三联关注我哟~...

  • 首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网...

  • 1.      SIGTERM “kill pid” 会发送SIGTERM到进程pid. This is the termination signal sent by killcommand by default. 2.      SIGINT 在终端中敲入interrupt key(DELETE或ctrl+c)会产生SIG...

  • 文章目录描述函数成员及使用总结 我们上一篇描述关于C++多线程中的异步操作相关库( async和 promise),本节将分享c++标准库中最后一个多线程异步操作库 package_task的学习笔记。 描述 头文件 声明方式: template< class R, class ...Args > c...

  • 关于如何在有噪声的数据中进行状态估计的问题的理解,状态估计的问题是指在运动和观测方程中,通常假设两个噪声ωiomega_i和υk,jupsilon_{k,j}满足零均值的高斯分布, xk=f(xk−1,uk)+ωkx_k=f(x_{k-1},u_k)+omega_k其中ωk→N(0,Rk)omega_k ightarro...

  • 强化学习(英语:Reinforcement learning,简称RL)是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益。其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予的奖励或惩罚的刺激下,逐步形成对刺激的预期,产生能获得最大利益的习惯性行为。这个方法具有普适性,因此在其他许多领域都有研究,例如博弈...

  • 文章目录PG 的状态机和peering过程1. PG 状态机变化的时机2. pg的状态演化过程3. pg状态变化实例讲解3.1 pg状态的管理结构3.2 数据的pg状态变化过程3.2.1 NULL -> initial3.2.2 initial -> reset -> Started3.2.3 Started(start) ->St...

  • 什么是状态模式? 定义:将事物内部的每个状态分别封装成类,内部状态改变会产生不同行为。 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。 何时使用:代码中包含大量与对象状态有关的条件语句。 如何解决:将各种具体的状态类抽象出来。 应用实例: 1、打篮球的时候运动员可以有正常状态、不正常状态和超...

  • 别小看这个功能, 感觉在写一些技术 Blog 的情况下还是挺有用的.   打开QQ拼音: 输入法设置->基本设置->初始状态->中文状态下使用英文标点.  转载于:https://www.cnblogs.com/qrlozte/p/4904087.html...