加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux 内核源码分析之进程简要及调度时机

发布时间:2022-01-14 12:24:51 所属栏目:Linux 来源:互联网
导读:人们在面对一个问题束手无策的时候,经常会创造一个概念,然后基于这个概念来演化出一个系统来解决这个问题。进程的概念就是人类发明出来,为了解决物理世界想要同时做若干件事情的需求,最终演化出了进程子系统。关于进程的基本知识网上有很多,这里说下我
   人们在面对一个问题束手无策的时候,经常会创造一个概念,然后基于这个概念来演化出一个系统来解决这个问题。进程的概念就是人类发明出来,为了解决物理世界想要同时做若干件事情的需求,最终演化出了进程子系统。关于进程的基本知识网上有很多,这里说下我的理解:
 
   加载器将可执行程序文件(Linux 中是 ELF 格式)加载到操作系统,操作系统中就多了一个进程。
 
   进程的核心由代码段和数据段组成,代码段就是进程在执行过程中按照正常流程一条条执行的指令,数据段就是指令需要的数据。 每颗 CPU 都有一个 PC(Program Counter)寄存器,这个寄存器指向了下一条要执行的指令地址,由于这个指令必然属于某个进程,所以,每个 CPU 每一时刻只能运行一个进程。

多线程在内核空间本质上也是多进程,多个进程在时间较大的尺度上给人一种可以同时执行的错觉,本质上是通过进程调度交叉执行,只不过这个时间太短,我们感觉不到而已。JVM 中的一个线程对应了 Linux 内核中的一个进程,了解了底层进程的机制,也就了解了上层的很多现象。

由于历史原因,内核中表示进程的数据结构叫做 task_struct,这个数据结构里面的字段有几十个,我不太想一一列出来,然后占很大篇幅。我会列几个大家比较关心的,在后面的分析过程中,会逐渐展开 task_struct 的其他字段。本篇文档对应的 Linux 内核是 5.0。

从上面的几个关键的字段可以看出,每个进程都有唯一的 ID 和状态,并且,在系统中,进程是通过一棵树的方式来组织的,也就是说,所有的进程都有父亲,通过我们熟悉的 fork 系统调用来创造。另外,Linux 内核中也是不区分进程和线程的,两者均使用 task_struct 数据结构,线程的本质是共享进程的资源,对应这个数据结构,只要把里面涉及共享的指针指向进程的资源即可。

「所有的进程都有父亲」,这句话不一定全对,就像演绎逻辑链一样,我们一直顺着大前提往上追,总会追到第一个 大 bug,这个 大 bug 我们无法证明,只能默认它是对的,它是我们系统的第一性原理。扯远了,Linux 中,这个 大 bug 就是 0 号进程,它的另一个外号叫 IDLE,这个 大 bug 在内核初始化的时候,被显示地定义出来(而不是通过 fork),下面我们来感受一下 Linux 进程子系统中第一个进程 无中生有 的过程。init_task 类似于盘古,系统中所有的进程都是由它开辟出来的,在后续的 Linux 内核文章中,我们会逐渐了解这个机制的妙处,我们先把注意力调回到本篇文章的重点,进程切换的机制。
 
进程是对物理世界的建模抽象,每个进程对应一个 task_struct 数据结构,这个数据结构包含了进程的所有的信息。在 Linux 内核中,不会区分线程和进程的概念,线程也是通过进程来实现的,线程和进程的唯一区别就是:线程没有独立的资源,进程有。
所有的进程都是通过其他进程创建出来的,因此,整个进程组织为一棵进程树。0 号进程是 无中生有 凭空产生的,是静态定义出来的,是所有进程的祖先。

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读