文章目录
- 1. 进程的概念
- 2. 进程描述—PCB
- 3. task_struct—PCB的一种
- 4. task_ struct内容分类
- 5. 查看进程
这篇文章我们来学习下一个概念——进程
1. 进程的概念
那什么是进程呢,我们该如何理解它呢?
如果我们打开电脑的任务管理:
我们看到这里面就展示了当前正在运行的进程,那大家看这其实就是我们当前打开的程序嘛
所以,我们给出一个结论:
我们以前任何启动并运行程序的行为,都是由操作系统帮助我们将程序转化为进程,来完成特定的任务。
那说到底进程到底是什么呢?我们继续来探讨探讨:
大家看这张图
那我们平时自己写好的可执行程序,我们知道它本质其实就是一个二进制文件嘛
那我们运行这个可执行程序,首先它被载入内存,其实就是把可执行程序里面的指令和数据加载到内存。
那此时它就变成一个进程了吗?
大家想一个问题,一个社会人进入到你的学校,他就是你们学校的一名学生了吗?
不是的。
那同样的,一个可执行程序或应用程序被加载到内存里面,他就变成了被操作系统管理的进程了吗?
好像也有点不合理。
那一个人如何才算你们学校的学生呢?
是不是它的学籍要在你们学校里,它的信息要在你们学校的教务管理系统上,这才是最关键的。
然后第二个问题,我们可能同时运行多个程序,那他们都要加载到内存里,就好比学校里面有好多学生,那学校肯定要对这么多学生进行一个良好的管理。
那同样的,操作系统也要对加载到内存的多个进程进行管理。
那如何进行管理呢?
很简单,还是我们之前说的——先描述,再组织
2. 进程描述—PCB
那如何描述进程呢?
进程信息被放在一个叫做进程控制块(PCB)的数据结构中,可以理解为进程属性的集合。
PCB是进程存在的唯一标识。
课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct
所以:
我们每运行一个程序,除了要把它对应的指令和数据加载到内存,操作系统还会为它创建一个PCB来记录和管理进程信息
那操作系统要管理这么多的进程,就可以把所有进程的PCB用一个数据结构比如链表管理起来(再组织)
那此后操作系统对于进程的管理就变成了对组织PCB的数据结构的管理
所以,回到我们上面说的:
一个程序被加载到内存,他就是进程了吗?
不是的
进程包括了程序加载到内存中的指令和数据,以及内核中与之关联的进程控制块(PCB)
所以,我们这里给出一个进程的概念:
进程=程序加载到内存中的指令和数据+内核中与之关联的进程控制块(PCB)
此外:
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
3. task_struct—PCB的一种
在Linux中描述进程的结构体叫做task_struct
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
4. task_ struct内容分类
task_ struct里面包含了以下内容:
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息
可以在内核源代码里找到它,所有运行在系统里的进程都以task_struct链表的形式存在内核里。
然后呢我们上面提到:
可执行程序其实就是一个文件嘛,而文件的话我们说过文件=内容+属性
那程序运行载入到内存里面的指令和数据这毫无疑问肯定是文件的内容。
然后呢我们有提到每个进程操作系统都会创建一个PCB来描述进程,可以理解为PCB就是进程的属性集合。
那请问这里的PCB即进程属性的结合跟可执行文件的属性有没有关系呢?
其实呢有关系,但是关系不大。
磁盘上文件的属性一般就是文件名、文件类型,位置,占用空间这些东西。
而PCB呢,它是由操作系统动态创建和维护的一种内核数据结构,它里面包含的进程的属性都是操作系统自己获取和记录的,跟文件的属性不是一回事,没什么关系。
其实也稍微有点关系,后面会带大家看。
5. 查看进程
那如何查看进程呢?
首先,我们先来写一个代码和makefile:
编辑一下myprocess.c
保存退出
然后我们把makefile写一下:
然后:
我们make一下
就生成了一个可执行程序myprocess
那我们./
执行这个可执行程序,操作系统就会把它加载到内存,同时为他建立PCB(在Linux上是task_struct),然后它就变成了进程
那我们如何查看这个进程呢?
让这个进程继续跑着,我们再打开一个渠道
然后我们输入一条命令
就可以看到我们刚才运行起来的进程
简单解释一下这条命令(这里的命令我们后面会讲)
ps axj | head -1 && ps axj | grep myprocess
这是是逻辑与连接了两条命令,首先ps axj
可以显示当前系统中所有进程的详细信息,但是我们不想看所有的,所以管道连接head -1
就是去只显示ps axj
展示出来的所有信息的第一行(即那个表头信息),然后&&后面又连接一条指令,其实就是过滤取出关键字myprocess对应的进程信息
然后下面那个大家可以不用管,它是因为grep这个也是一个进程,也被过滤出来了
当然可以把它屏蔽掉
就只剩我们的这一个了
那然后我们再打开一个渠道
也把这个程序运行起来
然后
我们就可以观察到两个了
然后我们来观察一下显示的信息:
我们看到有个PID,就是我们上面提到的进程的唯一标识符。
它们两个是不一样的,所以它们两个是不同的两个进程,虽然是同一个可执行程序运行生成的。
那除了上面查看进程的方式,还有其它方法:
我们还可以通过 /proc 系统文件夹查看进程信息
proc其实就是process的缩写嘛
/proc 目录是 Linux 系统中的一个特殊目录,提供了有关当前运行进程和内核状态的信息。
需要注意的是,它跟普通的文件不一样,它不是一个真正的文件系统,而是通过内核在内存中维护的一个虚拟文件系统。只有当操作系统启动的时候,它才会存在,并不存在于磁盘上。
但是这里我们好像没有看到process。
这里有很多数字,代表什么呢?
🆗,这些数字其实是特定进程的PID,我们是能找到上面我们两个process进程的PID的
这些数字是蓝色的,我们知道蓝色表示它是一个目录/文件夹。
所以:
一个进程被创建好,操作系统会自动在proc目录下创建一个以新增进程的PID命名的文件夹
我们可以进去看看
这里面有很多内容,这些内容其实就是当前进程的相关属性信息
这些东西大多我们还看不懂,但是
大家看这两个,不就是对应程序的路径吗。
那着就是我们前面说的进程的属性跟文件的属性也稍微有一点关系
那然后:
我们当前是在proc里面这个进程PID对应的这个目录里面的,上面说了PID对应的目录是进程创建的时候才会在proc目录下新增的。
那如果我们把对应的进程终止(CTRL+c)掉
在想查看这个目录的内容就不行了
上一级我们也回不去了。
因为进程终止,操作系统就会在proc目录下把这个进程PID对应的目录及其里面的内容删除掉。所以proc目录里面的内容是动态变化的。
这篇文章就先到这里,下一篇文章我们继续讲解进程相关的内容…