进程中的任务状态解析

news/2024/7/24 9:29:08 标签: linux

在 Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_struct 进行管理。

每一个任务都应该有一个 ID,作为这个任务的唯一标识。到时候排期啊、下发任务啊等等,都按 ID 来,就不会产生歧义。

task_struct 里面涉及任务 ID 的,有下面几个:

pid_t pid;
pid_t tgid;
struct task_struct *group_leader; 

所以在内核中,它们虽然都是任务,但是应该加以区分。其中,pid 是 process id,tgid 是 thread group ID。

任何一个进程,如果只有主线程,那 pid 是自己,tgid 是自己,group_leader 指向的还是自己。

但是,如果一个进程创建了其他线程,那就会有所变化了。线程有自己的 pid,tgid 就是进程的主线程的 pid,group_leader 指向的就是进程的主线程。

有了 tgid,我们就知道 tast_struct 代表的是一个进程还是代表一个线程了。

 task_struct 里面关于信号处理的字段。

/* Signal handlers: */
struct signal_struct    *signal;
struct sighand_struct    *sighand;
sigset_t      blocked;
sigset_t      real_blocked;
sigset_t      saved_sigmask;
struct sigpending    pending;
unsigned long      sas_ss_sp;
size_t        sas_ss_size;
unsigned int      sas_ss_flags;

这里定义了哪些信号被阻塞暂不处理(blocked),哪些信号尚等待处理(pending),哪些信号正在通过信号处理函数进行处理(sighand)。处理的结果可以是忽略,可以是结束进程等等。

信号处理函数默认使用用户态的函数栈,当然也可以开辟新的栈专门用于信号处理,这就是 sas_ss_xxx 这三个变量的作用。

state(状态)可以取的值定义在 include/linux/sched.h 头文件中。

/* Used in tsk->state: */
#define TASK_RUNNING                    0
#define TASK_INTERRUPTIBLE              1
#define TASK_UNINTERRUPTIBLE            2
#define __TASK_STOPPED                  4
#define __TASK_TRACED                   8
/* Used in tsk->exit_state: */
#define EXIT_DEAD                       16
#define EXIT_ZOMBIE                     32
#define EXIT_TRACE                      (EXIT_ZOMBIE | EXIT_DEAD)
/* Used in tsk->state again: */
#define TASK_DEAD                       64
#define TASK_WAKEKILL                   128
#define TASK_WAKING                     256
#define TASK_PARKED                     512
#define TASK_NOLOAD                     1024
#define TASK_NEW                        2048
#define TASK_STATE_MAX                  4096

TASK_RUNNING 并不是说进程正在运行,而是表示进程在时刻准备运行的状态。当处于这个状态的进程获得时间片的时候,就是在运行中;如果没有获得时间片,就说明它被其他进程抢占了,在等待再次分配时间片。

在运行中的进程,一旦要进行一些 I/O 操作,需要等待 I/O 完毕,这个时候会释放 CPU,进入睡眠状态。

在 Linux 中,有两种睡眠状态。一种是 TASK_INTERRUPTIBLE,可中断的睡眠状态。另一种睡眠是 TASK_UNINTERRUPTIBLE,不可中断的睡眠状态。

这其实是一个比较危险的事情,除非程序员极其有把握,不然还是不要设置成 TASK_UNINTERRUPTIBLE。TASK_KILLABLE,可以终止的新睡眠状态。进程处于这种状态中,它的运行原理类似 TASK_UNINTERRUPTIBLE,只不过可以响应致命信号。

TASK_STOPPED 是在进程接收到 SIGSTOP、SIGTTIN、SIGTSTP 或者 SIGTTOU 信号之后进入该状态。

TASK_TRACED 表示进程被 debugger 等进程监视,进程执行被调试程序所停止。当一个进程被另外的进程所监视,每一个信号都会让进程进入该状态。

一旦一个进程要结束,先进入的是 EXIT_ZOMBIE 状态,但是这个时候它的父进程还没有使用 wait() 等系统调用来获知它的终止信息,此时进程就成了僵尸进程。

EXIT_DEAD 是进程的最终状态。EXIT_ZOMBIE 和 EXIT_DEAD 也可以用于 exit_state。

此文章为10月Day23学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。


http://www.niftyadmin.cn/n/5114026.html

相关文章

Django设置跨域

1, 安装 pip install django-cors-headers 2, 添加应用 INSTALLED_APPS (...corsheaders,... ) 3, 中间层设置 MIDDLEWARE [corsheaders.middleware.CorsMiddleware,... ] 4, 添加白名单 # CORS CORS_ORIGIN_WHITELIST (127.0.0.1:8080,localhost:8080,www.meiduo.si…

软件开发项目文档系列之四如何成功撰写一份引人注目的投标文件

目录 前言1 分析招标文件1.1 投标的基础要求分析1.2 投标重点要求分析1.3 评分标准分析1.4 技术需求分析 2 撰写完整的投标文件2.1 明确文件用途2.2 提供评分指引2.3 内容完整重点突出2.4 重视图表和图示 3 认真检查和经验积累3.1 深入的准备3.2 反复检查3.3 咨询和确认3.4 积累…

【C++ 学习】链接、作用域、内存管理

链接、作用域、内存管理 存储类别 int num 3;该声明创建了一个名为num的变量,变量值为3,num是这个变量的名字,也就是标识符。标识符是一个名称,一个合法的标识符必须以字母或者下划线(_)开头&#xff0c…

CMMI V2.0能力域

1、概念 能力域是一组相关的PA,可以提高组织或项目的技能和活动的性能。能力域视图是CMMI模型的一个子集,描述了构成特定能力域的一组预定义PA。能力域是一种视图。如下面规划和管理工作能力域视图: 2、类别 类别是相关能力域的逻辑组或视图…

Oracle 数据库相关操作记录

1 数据库操作: 1.1 --调用存储过程: DECLARE P_DATA_DATE VARCHAR2(32767);--定义输入参数 P_O_RESULT VARCHAR2(32767); BEGIN P_DATA_DATE : 20220320;--输入日期 P_O_RESULT : NULL; TPS.PR_TP_RBC34_TMP ( P_DATA_DATE, P_O_RESULT );--输…

windows2008+iis7+asp+php环境配置

一、ASP配置 1、asp要开启父路径 2、防火墙开放端口。例如你的网站打算用8002端口而不是80,那防火墙要开放8002端口,否则就是开放80端口 3、iis添加默认访问页index.asp 4、c:/windows/temp增加iisxxx的 写入权限 给 C:\Window\Temp 目录&#xff0…

YOLOv8改进实战 | 更换损失函数之MPDIOU(2023最新IOU)篇

前言 YOLOv8官方默认损失函数采用的是CIoU。本章节主要介绍如何将MPDIoU损失函数应用于目标检测YOLOv8模型。 目录 一、MPDIoU二、代码实现添加损失函数更换损失函数一、MPDIoU 论文链接:MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression MPDIoU是一种基于…

【golang】mysql默认排序无法实现 使用golang实现对时间字符串字段的排序

一、问题场景 1、mysql实现排序-性能低下 例如:某字段 finish_time 数据如下:6:13:27、 10:56:11、 21:56:11 会出现顺序如下的场景: 10:56:11、 21:56:11、6:13:27 二、解决方案 2、golang实现排序 package mainimport ("fmt"&…