进程概念
进程是程序的一个执行实例,是正在执行的程序,担当分配系统资源(CPU时间、内存)的实体。
描述进程-PCB
进程信息被放在一个叫进程控制块的结构体中,可以理解为进程属性的集合。我们将它叫做PCB(process control block),Linux操作系统下的PCB是:task_struct。
task_struct是PCB的一种。
Linux描述进程用的是task_struct结构体,它是Linux内核的一种数据结构,会被装载到RAM里并且包含着进程的信息。
task_struct内容分类:标识符、状态、优先级、程序计数器、内存指针、上下文数据、I/O状态信息、记账信息、其他信息。
进程状态
- R运行状态(running):表明进程正在运行或者进程正在运行队列里,注意:并不意味着进程一定在运行中。
- S睡眠状态(sleeping):意味着进程在等待事件完成,也叫可中断睡眠。
- D磁盘休眠状态(Disk sleep):这个状态的进程通常会等待IO的结束,也叫不可中断睡眠状态。
- T停止状态(stopped):可以通过发送SIGSTOP信号来停止进程。
- X死亡状态(dead):这个状态只是一个返回状态,在任务列表里是无法看到的。
- Z僵尸进程,下面会详细说明僵尸进程。
僵尸进程
首先,我们先创建一个子进程出来,然后通过fork函数的返回值来让父子进程执行不同的代码。
我们来看一下这个代码的运行结果:
我们来查看一下进程状态信息:
子进程已经退出,父进程依旧处在不断循环的睡眠之中。
我们可以看到,子进程的进程状态是Z,说明子进程已经变成了僵尸进程。
变成这种情况的原因:
子进程先于父进程退出,子进程在退出的时候,会告知父进程,父进程接收到信息之后忽略处理,父进程并没有回收子进程的退出状态信息(退出码,退出信号、coredump标志位),从而导致子进程变成僵尸进程。
僵尸进程的危害
子进程的PCB没有被操作系统内核释放,从而导致内存泄漏。
kill 命令
kill [pid]:作用:终止一个正在运行的进程
此处测试用的test文件就是上文照片的代码。父进程一直没有结束。
对父进程执行kill命令前:
对父进程执行kill命令后:
我们再通过查看进程状态信息来看一下父子进程状态:
对父进程执行kill命令前:
对父进程执行kill命令后:
我们已经找不到父进程了,可以说明我们无限循环在sleep的父进程已经被我们kill掉了。
kill -9 [pid]:作用:强杀一个进程。
测试一下看一下效果:
对父进程执行命令前:
对父进程执行命令后:
如何解决僵尸进程
- 终止其父进程
- 重启操作系统
- 进程等待