文章目录
- 进程的概念
- 如何描述进程?
- **为什么要描述一个进程**?
- 进程描述--PCB
- task_struct
- 组织进程
- 查看进程
- 通过系统调用获取进程标示符
- getpid()以及getppid()
进程的概念
在【百度百科】中,关于进程----
狭义定义:进程是 正在运行 的程序的实例
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
根据以上定义我们可以得到关于经程的两个基本概念:
1.进程是一个实体。
实体,也就是意味着具有自己的地址空间,包括常量区、静态区、堆栈。
2.进程是动态执行的程序。
单单一个程序是没有生命的实体,如果被操作系统赋予了生命,那么就成为了一个进程。
总结:进程=PCB+程序(代码段、数据段)
如何描述进程?
为什么要描述一个进程?
何谓描述?描述就是把某个抽象的概念用一种形式表示出来,让我们能知道被描述对象到底是什么。
对于一个学校的管理层来说,要想更好的管理我们所有的学生,就需要了解我们学生的基本信息,并将其信息登记在学生表里面。学号、年级、姓名以及考试成绩等就是对我们学生的描述。
情景假设1:现在假设某个领导想去1班成绩最好的同学家访。
那么就只需要找到1班的学生表,再去找表里面的关键信息–成绩,比对一下就很容易找到目标学生了。
如果没有这张1班的学生表,排除其他因素干扰下,想找到成绩最好的学生就只能一个一个问了。这样显然不利于管理。
而对于操作系统来说,身为进程的管理员,操作系统同样也需要用统一的方式去描述一个进程。将某一个进程的基本信息提取出来并打包,存放在某个“表”(队列)的某一行里:PID、PPID、页表地址、进程状态等关键字就是对某个进程的描述。这样一来操作系统就能快速的知道目标进程的信息,也就能很好的管理进程了。
情景假设2:假如现在操作系统需要找到将键盘资源分配给某个进程。
那么我们就需要知道有哪些进程在等待键盘资源。于是,操作系统就拿到了类似成绩表的一个东西(等待队列),在这个“表”里面找到最前面的进程,根据描述信息“PID”快速找到进程A,再给进程A键盘资源。这就是操作系统为什么要描述进程的原因----方便管理。
以上例子可能跟实际情况有差别,但是想表达的意思是很清晰的,那就是:为了便于管理进程,在生成一个进程的时候操作系统就需要描述这个进程。
回归正题:操作系统是如何描述一个进程的?
进程描述–PCB
为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构。它是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,在创建进程时,建立PCB,伴随进程运行的全过程,直到进程撤消而撤消。
本质上PCB就是一个结构体,只不过在不同的操作系统中,其结构体的名称有所区别,比如windows下就叫做PCB,但是在Linux中的叫做==task_struct==。
task_struct
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_struct的内容分类:
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。 其他信息等
组织进程
我们知道了进程是如何被描述的,那么对于这么多进程操作系统又是如何将这些进程组织起来的呢?这里的组织,其实就是某种数据结构。就像每一个学生被描述成了一个包含“年级、姓名、成绩”的“元素”,将这些元素都组织在一个表里面。这里的组织方式就是一个类似线性表的“表格”。
查看进程
linux下进程的信息可以通过 /proc 系统文件夹查看,该文件夹存放了所有进程的信息,每一个进程的信息都是一个文件夹
大多数的进程我们同样可以使用top和ps这些用户级工具来获取
1.创建一个进程,运行以下代码
2.使用ps ajx|grep test|grep -v grep
指令查看test进程
通过系统调用获取进程标示符
进程id–PID (进程的身份证号,唯一标识一个进程)
父进程id–PPID
getpid()以及getppid()
观察以下代码:
哪个进程调用getpid(),就会得到哪个进程的PID.
当我们运行以上代码,就会建立相应的进程,通过getpid()获取到当前进程的PID,getppid()获得当前进程的父进程的PID.
test程序的父进程是谁呢?
bash,也是基本上所有指令进程的父进程。