1. 基本概念
- 课本概念:程序的一个执行实例,正在执行的程序等
- 内核观点:担当分配系统资源(CPU时间,内存)的实体
2. 描述进程-PCB
- 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
- 课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct
- 一个进程一定要有一个PCB
2.1 task_struct-PCB的一种
- 在Linux中描述进程的结构体叫做task_struct。
- task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
2.2 task_ struct内容分类
- 标示符: 描述本进程的唯一标示符,用来区别其他进程。
- 状态: 任务状态,退出代码,退出信号等。
- 优先级: 相对于其他进程的优先级。
- 程序计数器: 程序中即将被执行的下一条指令的地址。
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
- 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
- 其他信息
2.3 tast_struct的属性
1.启动
- ./XXXX 本质就是让系统创建进程并运行 --- 我们自己写的代码形成的可执行 == 系统命令 == 可执行文件(在Linux中运行的大部分执行操作,本质都是运行进程)
ps axj 命令
ps和grep本身也是命令,启动也是一个进程
可以用head命令只显示头部信息
如果我们同时想看到头部信息和进程信息,我们可以用&&,这样就都可以显示出来了
PID
- 每一个进程都要有自己的唯一标识符,叫做进程PID
- 一个进程,想知道自己的PID,可以用系统调用getpid
如何证明呢?
PPID
getppid --- 获得当前进程的父进程id
每次启动的PID不一样是正常的,但是PPID是相同的
我们grep一下这个PPID
对应Windows就是我们的任务管理器
在Windows中双击就启动进程了,Linux中./就启动进程了
2.终止
在Windows中可以通过×关闭进程,在Linux中可以通过ctrl+c关闭,也可以通过kill杀死进程
3.创建进程
进程创建的代码方式 --- 重(zhong)操作、轻原理
创建进程就是操作系统中多了一个进程,多了一个进程就是多了一个PCB和对应的代码数据
fork
我们可以写一个监控脚本,让进程管理器每一秒刷新一次
while :; do ps axj | head -1 && ps axj | grep myprocess;sleep 1;done
如何证明呢,getpid和getppid都只能调用该进程的pid和ppid
为什么要创建子进程
想让子进程执行和父进程不一样的代码
fork会返回两个返回值
kill掉任何一个进程都不会影响另一个进程,只不过kill掉父进程,子进程会到后台运行
创建多个子进程
3. 组织进程
- 可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里
4. 查看进程
- 进程的信息可以通过 /proc 系统文件夹查看
进程中的PCB会记录自己对应的可执行程序的路径
cwd:current work dir 进程的当前工作路径
我们将这个可执行程序删除
但是进程还在运行,原因是我们删除的只是磁盘上的文件,但是一个程序在被调用的时候会先在内存里存一份,所以删除磁盘上的文件,不影响内存