专栏首页人人都是极客Linux 内核进程管理之基础

Linux 内核进程管理之基础

没有废话,内存管理暂时告一段落,正式进入进程管理的内容。

内核通过 task_struct 描述进程

用命令 pstree 可以让内核以树形的结构把进程之间的关系列出来,如下图:

这是进程在内核中的结构形式,那么内核是如何来以树形结构管理描述这些进程的呢?用来描述进程的数据结构,可以理解为进程的属性。比如进程的状态、进程的标识(PID)等,都被封装在了进程描述符 task_struct 这个数据结构中。

struct task_struct {
  ......
 /* -1 unrunnable, 0 runnable, >0 stopped: */
 //任务状态。<0是不运行状态,=0是运行状态,>0是停止状态。
 volatile long   state;
 ......
 //指向内核栈的指针
 void    *stack;
 ......
 /*进程的调度策略,有6种。
 *限期进程调度策略:SCHED_DEADLINE。
 *实时进程调度策略:SCHED_FIFO,SCHED_RR。
 *普通进程调度策略:SCHED_NORMAL,SCHED_BATCH,SCHED_IDLE。
 */
 unsigned int   policy;
 ......
 //进程内存管理信息
 struct mm_struct  *mm;
 struct mm_struct  *active_mm;
 ......
 //进程标识符,用来代表一个进程
 pid_t pid;    
 ......
 //线程链表
 struct list_head  thread_group;
 struct list_head  thread_node;

 struct completion  *vfork_done;
 ......
 /* Filesystem information: */
 //文件系统信息
 struct fs_struct  *fs;

 /* Open file information: */
 //打开文件信息
 struct files_struct  *files;
 ......
 /* CPU-specific state of this task: */
 //进程的CPU状态,切换时,要保存到停止进程的task_struct中
 struct thread_struct  thread;
 ......
};

内核就是通过list_head链表把各个进程关系以树形结构管理起来的。

task_struct 结构体内容太多,这里只列出部分成员变量,感兴趣的读者可以去源码 include/linux/sched.h头文件查看。

task_struct 中的主要信息分类:

  1. 标示符:描述本进程的唯一标识符 pid,用来区别其他进程。
  2. 状态:任务状态,退出代码,退出信号等
  3. 优先级:相对于其他进程的优先级
  4. 程序计数器:程序中即将被执行的下一条指令的地址
  5. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  6. 上下文数据:进程执行时处理器的寄存器中的数据
  7. I/O状态信息:包括显示的I/O请求,分配的进程I/O设备和进程使用的文件列表
  8. 记账信息:可能包括处理器时间总和,使用的时钟总和,时间限制,记帐号等
  • ARM64不用通过struct thread_info thread_info获取当前task_struct
static __always_inline struct task_struct *get_current(void)
{
        unsigned long sp_el0;

        asm ("mrs %0, sp_el0" : "=r" (sp_el0));

        return (struct task_struct *)sp_el0;
}

#define current get_current()

可以看出 sp_el0 直接作为 task_struct 返回了。对于ARM64平台,记录当前进程的task_struct地址是利用sp0_el1寄存器,当内核执行进程切换时会把当前要运行的进程task_struct地址记录到该寄存器中。因此我们current查找task_struct时也是很简单了,不再用通过sp和thread_info去定位了。

  • volatile long state

-1是不运行的,=0是运行状态,>0是停止状态

Linux中的 ready 和 running 对应的都是TASK_RUNNING标志位,ready 表示进程正处在队列中,尚未被调度;running 则表示进程正在CPU上运行;

  • void *stack

指向内核栈的指针,内核通过 dup_task_struct 为每个进程都分配内核栈空间,并记录在此。

  • struct mm_struct *mm

与进程地址空间相关的信息。

task_struct 的分配和初始化

图中可知,上层应用通过各种方式创建进程时,最终都会通过 _do_fork 新建一个 task_struct。

本文分享自微信公众号 - 人人都是极客(rrgeek),作者:布道师Peter

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【Linux内核】进程管理

    进程是Unix操作系统最基本的抽象之一。一个进程就是处于执行期的程序(目标码存放在某种存储介质上)。但进程并不仅仅局限于一段可执行程序代码(Unix称其为代码段...

    看、未来
  • Linux基础:进程管理

    任何进程都与文件关联;我们会用到lsof工具(list opened files),作用是列举系统中已经被打开的文件。在linux环境中,任何事物都是文件,设备...

    码农架构
  • Linux内核设备驱动之Linux内核基础笔记整理

    静态加载, 把驱动模块编进内核, 在内核启动时加载 动态加载, 把驱动模块编为ko, 在内核启动后,需要用时加载

    砸漏
  • Linux基础学习(七)进程管理

    此篇系学习邹圣林老师的进程管理后的个人笔记,进程管理当前属于该系列第7篇文章,其他学习笔记将经过分类学习后逐渐发表在本网站。

    Weiyang
  • 通过fork来剖析Linux内核的内存管理和进程管理(上)

    本文主要从内存管理和进程管理两个维度来窥探一下fork背后隐藏的技术细节,希望能够通过本文让大家站在一个高度去看进程创建。

    刘盼
  • 通过fork来剖析Linux内核的内存管理和进程管理(下)

    上一篇文章我们讲到fork的时候内存管理相关的内容,时间大概隔了快一周了,发布下篇文章,写文章确实费时费力,需要仔细推敲,原创不易,希望大家多多支持吧。本文讲解...

    刘盼
  • linux之进程管理

    用户 进程Id 占用cpu 占用内存 虚拟内存 物理内存 使用的终端 当前状态 启动时间 占用cpu总计时 ...

    西西嘛呦
  • Linux进程内存管理(二)

    进程启动后,在 jemalloc 载入的时候会调用 jemalloc_constructor 执行一些初始化操作。这里利用了编译器的一些特殊支持,让函数在库加载...

    linjinhe
  • Linux进程内存管理(一)

    Linux 环境下,进程的内存管理器默认是使用 glibc 实现的 ptmalloc 。另外,还有两个比较有名的内存管理器:google 的 tcmalloc ...

    linjinhe

扫码关注云+社区

领取腾讯云代金券