1.PID和PPID
PID:查询的就是当前的这个进程的编号,我们把当前的这个进程结束之后,再次进入的时候就会发现这个进程的编号发生了变化,这个是非常的正常的,但是我们也可以发现其实这个PPID是一直没有发生变化的,这个PPID对应的是我们的当前的这个进程的父进程的编号,也就是我们的bash进程;
2.代码创建进程
fork函数创建进程:这个函数本质上就是一个系统的调用;
fork函数创建子进程的时候,这个子进程会在我们的操作系统内核里面创建新的这个进程控制块,但是这个代码和数据还是指向我们的父进程的代码和数据;

写实拷贝:当我们的这个子进程企图对于我们的这个数据进行修改的时候,我们的这个操作系统就会在底层上面对于这个数据进行拷贝,这个时候我们的这个子进程修改的数据就是我们的拷贝之后的数据,这个就是写实拷贝,我们的这个父进程对应的自己的数据是不变的;
进程的独立性:进程的PCB独立 的,进程的这个写实拷贝是独立的;
因为这个return执行的时候,我们的这个父进程和子进程都是已经被创建 的,我们的这个return就可以理解为对于数据进行修改,因此我们的这个父进程和子进程得到的是不同的返回值,相当于每一个进程得到的是不同的返回值;
3.进程状态
进程的状态也是属于进程的属性,因此这个进程的状态信息也是存在于我们的这个进程控制块PCB里面;
在我们的这个PCB里面,实际上这个进程的状态就是一个整数;
3.1运行状态
每一个CPU都对应着一个调度的队列,这个调度队列里面的PCB对应的就是就是运行或者是就绪的进程;

3.2阻塞状态
当我们的这个调度队列里面的PCB需要等待这个硬件设备的输入之类的操作的时候,没有等到,这个时候会从调度队列跑到这个硬件设备对应的队列里面去,等待着我们的硬件设备的相关操作,这个时候就是阻塞的;
当我们的硬件设备完成相关操作,操作系统收到信号,这个时候把我们的这个PCB重新调度到这个调度队列里面去,再次处于运行状态;
状态的改变实际上就是这个数据结构的改变,从原来的这个调度队列转移到了这个硬件对应的队列上面去,等到资源的供给;
3.3阻塞挂起
把这个进程对应的代码和数据挂到这个磁盘外设上面去

3.4运行挂起
当我们的这个内存资源严重不足的时候,我们的这个操作系统甚至有可能直接把这个正在调度的这个队列上面的后面的PCB直接转移到这个磁盘上面去,也就是使用的我们的页面的换入换出的相关的算法,都是有可能的,因此这个挂起不是单一的状态 ,例如这个阻塞挂起 和运行挂起都是存在的;
4.linux里面的进程状态
4.1两种休眠状态
浅度睡眠和深度睡眠:浅度睡眠就是我们的这个进程是可以被我们的这个操作系统杀死的,例如我们的这个操作系统里面的资源非常的短缺,但是我们的这个进程因为这个磁盘的读取之类的原因,这个时候我们的操作系统就可以杀死这个正在空闲的进程,这个进程就是我们说的浅度睡眠,是可以被我们的操作系统kill掉的;
但是如果这个进程和磁盘之间的这个交互的内容是我们的银行的数据呢,这样的情况即使我们的这个操作系统资源紧张,但是因为这个数据的重要性,我们的这个操作系统也不能把这个进程杀死,这个就是深度睡眠的状态;
4.2僵尸进程
当我们的这个子进程退出的时候,这个相关的信息不会立即被我们的这个操作系统回收掉,他需要把这个相关的退出信息维护一下,等待我们的父进程的处理,父进程一直不处理,这个子进程就会一直处于这个僵尸进程的状态;
4.3暂停两个状态
下面的这个主要就是两个暂停的状态的具体的区别和说明:

5.两个小知识点
5.1内存泄漏
当我们的这个进程退出的时候,这个对应的内存泄漏的情况其实是消失了的;
因此对于短暂的这个进程,诸如我们写一个程序运行,但是因为这个进程很快就结束了,因此这个里面的内存泄漏我们是不需要关心的;
我们真正的需要关系的是自启动的进程,他们会一直运行,这样的进程出现内存泄漏才是真正的需要我们注意的;
5.2task_struct缓存
这个二级标题起的不是很合适,但是符合我想要表达的这个意思,当我们的这个进程使用完成的时候,我们可以不直接回收掉,而是放到这个对应的链表里面去,例如这个unuse链表;
这个时候当我们的操作系统想要创建新的进程的时候,可以直接使用这个unuse链表里面的这个进程填入对应的这个信息即可,这样就实现了我们的这个task_struct的复用,实现了这个类似于缓存的效果;