进程概念
1、什么是进程
进程是一个PCB(进程控制块),是一个运行程序中的描述;在linux下是一个task_struct结构体,通过这个结构体实现操作系统对运行中程序的调度管理。
1.1 task_struct结构体
task_struct结构体是Linux内核中的一种数据结构,他会被装载在RAM(内存)中并包含进程的信息。
1.2 task_struct内容分类
- 标识符:描述本进程的唯一标识符,用于区别与其他进程
- 状态:任务状态、退出信号、退出代码等
- 优先级:相较于其他进程的优先级
- 程序计数器:程序即将执行的下一条指令的地址
- 内存指针:包括程序代码和进程相关数据的指针,也包括其他进程共享内存块的指针
- 上下文数据:上一次正在处理的数据
- I/O状态信息:包括显示的I/O请求、分配给进程的I/O设备、被进程 使用的文件列表
- 记账信息:记录当前一个程序已经在CPU上运行的时间
- 其他
1.3 CPU的分时机制
进程在操作系统中调度是切换运行的,每个进程都有一个CPU的时间片(一个进程在CPU上运行的时间段),在CPU上时间片运行完毕后切换到下一个进程。
1.4 进程的查看
进程查看指令是:ps
终端查看指令是:tty
ps -ef 查看的信息较为粗略(-e表示查看所有的,f表示以 树状的形式查看)
ps -aux 查看的信息比较详细
快速的定位查看信息:ps -ef | grep [文件名]
2、进程状态
进程状态查看指令:ps aux 或 ps axj
运行:正在运行的进程
就绪:拿到时间片就能运行,处于等待的状态
阻塞:没有在运行
2.1 在linux下的进程状态
- 运行状态R(Runing):包括正在运行的以及拿到时间片就能运行的
- 可中断休眠状态S(sleeping):进程在等待时间完成,也可称为睡眠状态
- 不可中断休眠状态D(Disk sleep):通常会等待IO的结束,也可称为磁盘休眠状态
- 停止状态T(stopped):通过发送SISTOP信号来停止进程,可以发送SICONT信号来开始进程
- 僵死状态Z(zombie):进程已经退出,但是资源没有完全释放
2.2 僵尸进程
僵尸进程:处于僵死态的进程(进程已经退出,但是资源没有完全释放
)
产生僵尸状态的原因
子进程先于父进程退出
,退出后,为了保存自身的退出原因(返回值),因此资源没有完全被释放,操作系统这时候通知父进程获取子进程的退出状态,并允许操作系统释放资源,但是若父进程没有关注这个退出状态,则子进程虽然退出了,但是资源没有完全被释放,处于僵死状态,这个进程称为僵尸进程。
总的来说就是:子进程先与父进程退出,但是父进程没有关注子进程的退出状态,导致子进程的资源没有完全被释放,故子进程进入僵死状态
僵尸进程的危害
- 若父进程不读取子进程的退出状态,则子进程就一直处于僵死状态
- 当子进程处于僵死状态时,父进程可能会读取其状态信息,所以PCB要一直进行数据维护
- 当创建子进程并不回收就会造成资源浪费
资源泄漏
僵尸进程的避免
进程等待:等待任意一个子进程的退出,获取退出子进程的返回值,并且释放子进程的资源,防止出现僵尸进程
- 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
- 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
- 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
- 连续fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。
2.2 孤儿进程
父进程先于子进程退出
,子进程就成为了孤儿进程,运行在系统后台,并且被1号进程(init进程)收养。此时孤儿进程退出后不会称为僵尸进程,资源立即被回收。
杀死进程的指令:kill + 进程id(只能杀死运行或休眠中的进程)
杀死一个停止的进程指令:kill -9 + 进程id
2.3 守护进程/精灵进程
详细查看博客:守护进程已经创建守护进程