一. 进程介绍
- 正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。
①. 孤儿进程
- 孤儿进程:一般情况下,子进程是由父进程创建,而子进程和父进程的退出是无顺序的,两者之间都不知道谁先退出。正常情况下父进程先结束会调用 wait 或者 waitpid 函数等待子进程完成再退出,而一旦父进程不等待直接退出,则剩下的子进程会被init(pid=1)进程接收,成会孤儿进程。
②. 僵尸进程
- 僵尸进程:如果子进程先退出了,父进程还未结束并且没有调用 wait 或者 waitpid 函数获取子进程的状态信息,则子进程残留的状态信息( task_struct 结构和少量资源信息)会变成僵尸进程。
③. 守护进程
- 守护进程( daemon) 是指在后台运行,没有控制终端与之相连的进程。它独立于控制终端,通常周期性地执行某种任务 。 守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断 。
④. 危害和解决
危害
- 孤儿进程结束后会被 init 进程善后,并没有危害,而僵尸进程则会一直占着进程号,操作系统的进程数量有限则会受影响。
解决
- 一般僵尸进程的产生都是因为父进程的原因,则可以通过 kill 父进程解决,这时候僵尸进程就变成了孤儿进程,被 init 进程接收
⑥. 守护进程创建的步骤
1. 创建子进程,父进程退出
- 所有工作在子进程中进行
- 形式上脱离了控制终端
2. 在子进程中创建新会话
- setsid()函数
- 使子进程完全独立出来,脱离控制
改变当前目录为根目录
- chdir()函数
- 防止占用可卸载的文件系统
- 也可以换成其它路径
重设文件权限掩码
- umask()函数
- 防止继承的文件创建屏蔽字拒绝某些权限
- 增加守护进程灵活性
关闭文件描述符
- 继承的打开文件不会用到,浪费系统资源,无法卸载
- getdtablesize()
- 返回所在进程的文件描述符表的项数,即该进程打开的文件数目