一步一步学linux操作系统: 09 进程数据结构_task_struct字段_任务 ID、信号处理、任务状态、进程调度

统一的结构 task_struct

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

图片来自极客时间趣谈linux操作系统

Linux 内核有有链表串联所有task_struct,struct list_head tasks;
task_struct 相关源码位置:
linux-4.13.16\include\linux\sched.h

任务task_struct包含的字段

任务 ID

每一个任务都应该有一个 ID,作为这个任务的唯一标识

pid_t pid;
pid_t tgid;
struct task_struct *group_leader; 

在这里插入图片描述
pid(process id, 线程的id);
tgid(thread group id, 所属进程[主线程]的id);
group_leader 指向 tgid 的结构体的指针

任何一个进程,如果只有主线程,那 pid 是自己,tgid 是自己,group_leader 指向的还是自己。
创建了其他线程,pid是线程自己的id,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 指定

任务状态

task_struct 里面,涉及任务状态的几个变量:

 volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
 int exit_state;
 unsigned int flags;
state(状态)可以取:
/* 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

在这里插入图片描述
state 是通过 bitset 的方式设置的

几种任务状态

图片来自极客时间趣谈linux操作系统
TASK_RUNNING:表示进程在时刻准备运行的状态,而不是说进程正在运行,获得时间片,就在运行中

睡眠状态:可中断; 不可中断; 可杀

  • TASK_INTERRUPTIBLE,可中断的睡眠状态
    收到信号要被唤醒
  • TASK_UNINTERRUPTIBLE,不可中断的睡眠状态
    收到信号不会被唤醒, 不能被kill, 只能重启
  • TASK_KILLABLE,可以终止的新睡眠状态
    可以响应致命信号, 由不可中断与 TASK_WAKEKILL 组合
    #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)

停止状态 TASK_STOPPED:由信号 SIGSTOP, SIGTTIN, SIGTSTP 与 SIGTTOU 触发进入
调试跟踪 TASK_TRACED:被 debugger 等进程监视时进入

结束状态

  • EXIT_ZOMBIE, 父进程还没有使用 wait()等系统调用来获知它的终止信息,此时进程就成了僵尸进程
  • EXIT_DEAD, 最终状态

标志flags

#define PF_EXITING    0x00000004
#define PF_VCPU      0x00000010
#define PF_FORKNOEXEC    0x00000040

在这里插入图片描述

  • PF_EXITING 表示正在退出
  • PF_VCPU 表示进程运行在虚拟 CPU 上
  • PF_FORKNOEXEC 表示 fork 完了,还没有 exec

进程调度

task_struct用于调度的部分字段:

//是否在运行队列上
int        on_rq;
//优先级
int        prio;
int        static_prio;
int        normal_prio;
unsigned int      rt_priority;
//调度器类
const struct sched_class  *sched_class;
//调度实体
struct sched_entity    se;
struct sched_rt_entity    rt;
struct sched_dl_entity    dl;
//调度策略
unsigned int      policy;
//可以使用哪些CPU
int        nr_cpus_allowed;
cpumask_t      cpus_allowed;
struct sched_info    sched_info;

在这里插入图片描述

task_struct 数据结构全览

图片来自极客时间趣谈linux操作系统

参考资料:

趣谈Linux操作系统(极客时间)链接:
http://gk.link/a/10iXZ
欢迎大家来一起交流学习

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值