📕进程
📕基本概念
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
当有程序运行的时候,会将对应的程序加载到内存中,这时操作系统为了能够进行更好的管理这些被加载进内存的程序,就会给每一个程序的属性等信息用一个结构体存储起来,并且该结构体中还存储着有一个该结构体指针,指向下一个被加载到内存中,操作系统给它存储属性的结构体,如下图:
📕描述进程-PCB
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block),PCB是操作系统学科的叫法,Linux操作系统下的PCB是: task_struct
task_struct-PCB的一种
- 在Linux中描述进程的结构体叫做task_struct。
- task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
CPU在进行进程调度的时候, 本质进程排队,其实就是让进程的PCB去排队,而不是可执行程序去排队,CPU找到了对应CPB,就找到了可执行程序,包括它的属性信息。
未来,所有对进程的控制和操作,都只和进程的PCB有关,和可执行程序无关。
📕总结:
- 对进程的管理,转化成了对PCB的管理。转为为了对PCB链表的增删查改(如上图);
- 进程 = 和执行代码 + 内核数据结构(
对应的内核PCB对象);
📕 pc指针/eip寄存器
- cpu内部其实有一个名字叫eip的寄存器的(有人有人也把他叫做pc指针),这个指针指向的是一个正在运行的程序,它指向谁,代表谁正在运行。
- 比如当我么在调试代码的时候,编译器是怎么知道我们运行到哪一行了呢?
- 其实是pc指针,指向的是长在运行的下一行代码,每次CPU都会在eip寄存器中读取内容,读取完执行,这时候pc指针++指向下一行,然后CPU再读取执行。
代码中的判断,循环,函数的跳转,本质就是pc指针在改变。
📕ask_ struct内容分类
- 标示符: 描述本进程的唯一标示符,用来区别其他进程。
- 状态: 任务状态,退出代码,退出信号等。
- 优先级: 相对于其他进程的优先级。
- 程序计数器: 程序中即将被执行的下一条指令的地址。(pc指针)
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针,拿到该指针能够找到可执行程序的代码和数据。
- 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。 - 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
- 其他信息
📕查看进程
指令:ps axj
如下图:
但我们将test.c(里面的伪代码为:一直打印)编译形成code可执行文件,当我们运行这个可执行程序时,会一直打印,一直处于运行状态,然后通过另一个窗口查看进程的时候,会发现code对应的进程与一些相关信息,但是,code进程下面Negev进程是什么呢?因为我们在查看进程的时候,指令grep也在运行,也是一个进程。(几乎所有的独立的指令,即使程序,运行起来也要变成进程)
、
📕杀进程
方法一:
当程序在运行的时候,ctrl+c可以终止这个进程。
方法二:kill + 进程编号
📕查看进程pid
函数 getpid与getppid ,没有参数,返回值类似于为C语言中int
使用方法:谁调用这个函数,就获取谁的pid
运行结果:
注意:
一般在Linux中,普通的进程都会有它的父进程。
每一次启动进程的pid几乎都会发生改变,因为我的进程是一个新的进程。
但是它的父进程一般不会改变,在命令启动的所有进程的父进程都是bash,命令行解释器。
验证: