一、前言
上篇文章我们简单的介绍了PCB(task_struct)的属性,下面讲一下标识符和状态以及在讲的过程中引出的的知识和命令
二、标识符
2.1pid
pid是标识进程唯一的标志,我们可以通过getpid();获取进程的id,返回值是pid_t(也就是int,只是typedef了)
比如我运行的一段C语言的简单死循环的程序(不是死循环运行进程就结束了)

2.2ppid
也叫做父进程,我们每个进程都有父进程,比如上面创建的进程也有父进程,是bash命令解释器,查看父进程id是getppid();

2.3创建子进程——fork()
如果要对该进程下创建子进程就需要fork()系统函数调用接口


返回值位pid_t,如果返回0j就是子进程,如果返回值大于0,是父进程,返回-1就是创建子进程失败
下面是实例:

这里也会延伸出几个疑问:
问题一:为什么创建的子进程返回0,而父进程返回子进程的pid呢
因为子进程本身只有一个,父进程可以有多个子进程,为了区分是执行哪个子进程所以返回的是pid,也就是日常生活一个孩子只有一个爸爸,一个爸爸能有多个孩子,孩子都有自己的名字,爸爸知道了名字就知道是哪个孩子!!!
问题二:上面一段代码怎么执行了两次if语句呢?

前台运行和后台运行
我们可以让程序在后台运行就是可以在显示器上输入其他指令通过./可执行程序 &这个就可以实现

这也像我们手机的后台程序一样不删除不会结束运行
2.4查看进程
查看进程在哪里可以通过ls /proc查看所有进程
ps aux / ps axj 命令
• a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
• x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
• :显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息
• u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况



由上通过 ls /proc/ -l 可以看出进程是个文件,

再详细看的话exe就是当前程序运行的路径,cwd是进程所处的路径
三、进程状态
3.1操作系统书籍讲的状态

就绪状态和运行状态
创建状态不多说, 就绪状态就是一个进程在一个调度队列中准备与CPU进行交互
调度队列:FIFO的形式先进先出(真实每个操作系统的实现队列的形式不同,这里就讲最常见的队列形式),管理的是PCB结构体

注意:但很多书上都是把在调度队列中的进程就称在运行状态,我们普遍都是这样的认知,所以以后没有特殊条件就认为在调度队列中的进程就称为运行状态
阻塞状态
就是在运行的进程需要键盘输入等操作时才能进行下一步操作,常见的就是scanf/cin输入
大概过程就是该进程会先从调度队列脱离,等键盘输入数据后,因为操作系统是对硬件的管理者所以它会最先知道数据已经输入,本质也是硬件设备其实也是结构体比如:
struct device{
//…
struct task_struct waite_queue
然后再回到调度队列里再与CPUjiaohu交互

阻塞挂起状态
当内存不够时,OS会将在阻塞状态的进程的数据先拷贝到磁盘特定的区域内,内存够了再重新回到内存中
就绪挂起状态
也就是在调度队列中的进程也有可能因为内存不足而不执行等内存足够再与CPU调度,也就是我们可能打开一个应用闪退的效果,可能就是你的后台占太多了应用
3.2Linux下的进程状态
下面的结构体就是Linux源码的状态

状态显示也是通过ps命令查看的
R状态
并不意味着进程⼀定在运⾏中,它表明进程要么是在运⾏中要么在运⾏
队列⾥。

S状态
意味着进程在等待事件完成(这⾥的睡眠有时候也叫做可中断睡眠
(interruptible sleep))
常见的就是我们scanf输入

但是拿上面我们讲的父子进程分流的代码运行时状态不是R+,是S+

原因就是:我们printf打印到显示器中本质是底层调用了系统接口write()函数,我们用户的缓冲区的数据是先同构write接受的当他接受到一定量时会停止接收,先向显示器打印释放掉,那这个等待过程就是休眠状态,所以99%的情况是S状态,很少情况能看到R状态也就是向wirte()输入数据
D状态
D磁盘休眠状态(Disksleep)有时候也叫不可中断睡眠状态(uninterruptiblesleep),在这个状态的进程通常会等待IO的结束。
与S的区别:补充知识:就是当内存不足时,OS可以选择性的杀死也就是结束掉一些休眠状态的进程以保证其他正在运行的进程的状态,OS可以杀死S状态的进程,不可以杀死D状态的进程, D状态往往是与磁盘交互把内存里的数据写入到磁盘上,如果一旦杀死进程磁盘不能收到进程的信号也就会直接把写入的数据删除这往往是很严重的!!!
比如:这个进程是500MB的银行存款账单信息,你一旦因为内存不够而杀死写入到对应磁盘中,就相当于损失了千万或亿的数据是很严重的
T状态
T停⽌状态(stopped):可以通过发送SIGSTOP信号给进程来停⽌(T)进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运⾏

通过kill -19 +pid停止进程 kill-18 +pid恢复暂停的进程
X状态和Z
X;就是死亡状态,进程结束时的状态我们一般看不到,它是把代码和数据清理掉,进程还在,但是一般进程都是被系统管理它会帮你把PCB给清理掉
Z: 僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后
⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程
• 僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
• 所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态

**把子进程给杀掉后就只打印父进程的代码了可以看到ps命令子进程状态变为了Z+,defunct意思为已故的,只要当父进程收到了子进程的提出代码就会从Z->X
僵尸状态可能引起内存泄漏
当你的父进程不是bash也就是系统时,如果你的程序是常运行的,你如果结束掉子进程而没有给父进程退出码删掉子进程的PCB的话就会导致这部分的无用的PCB占用内存久而久之严重的话就会使整个系统崩溃,所以一定要小心,怎么给退出代码下篇文章会讲!!!
孤儿进程
如果子进程的父进程被杀死后,这个子进程就是孤儿进程,它会被操作系统管理,你再杀掉子进程系统会帮你回收这里不会发生内存泄漏




