孤儿进程、僵尸进程、守护进程

进程的各种状态

运行状态(R:runing):运行状态的进程并不意味着此时的进程一定在运行,它表明进程要么在运行,要么在运行队列里。

睡眠状态(S:sleeping):进程在等待着事件完成。

磁盘休眠状态(D:disk sleep):也称不可中断睡眠状态,这个状态的进程通常会等待I/O的结束。

停止状态(T:stopped):可以通过发送SIGSTOP信号给进程来终止停止状态的进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行。

死亡状态(X:dead):这个状态的进程只是一个返回状态,任务列表里看不到这个状态的进程。

僵尸进程(Z:zombie):僵尸进程是一个比较特殊的状态。当进程退出且父进程没有使用wait()读到子进程退出的返回代码时就会产生僵尸进程。僵尸进程会以终止状态继续保持在进程表中,并且一直在等待进程读取退出状态代码。只要进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程就将进入僵尸状态。

僵尸进程

一个进程使用fork()创建子进程后,如果子进程退出,但是父进程并没有wait()或waitpid()来获取子进程的状态信息,那么子进程的描述符就将仍然保存在系统中。此时这种状态的进程就称为僵尸进程。僵尸进程是一个进程必然会经过的过程,这是每个子进程在结束时都要经过的阶段。僵尸进程可以通过ps命令来查询,显示出来的状态为Z(zombie)。

僵尸进程的危害:

我们都知道系统所能使用的进程号是有限的,如果大量的僵尸进程产生,将因为没有可用的进程号而导致系统不能产生新的进程,从而使得进程被init所收养,这样init就会释放所有的僵尸进程所占有的资源,从而结束僵尸进程。

僵尸进程的清除:

(1)外部消灭:通过kill发送SIGTERM或者SIGKILL信号消灭产生僵尸进程的进程,它产生的僵尸进程就变成了孤儿进程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源。

(2)子进程退出时向父进程发送SIGCHLD信号,父进程处理此信号,在信号处理函数中调用wait()处理僵尸进程。

(3)fork()两次来清除僵尸进程。原理是将子进程变为孤儿进程,从而使其父进程变为init进程,通过init进程来处理僵尸进程。父进程fork()一个子进程,然后继续工作,子进程再fork()一个子进程,即孙进程后退出,那么孙进程就将被init接管,孙进程结束后,init会回收。不过,子进程的回收还是要自己处理。

孤儿进程

一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)收养,并由init进程对它们完成状态收集工作,由于孤儿进程会被init进程收养,所以孤儿进程不会对系统造成危害。

守护进程

守护进程又称精灵进程,是独立运行于后台、常驻内存的特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。一个守护进程的父进程是init进程。因为它真正的父进程在fork()出子进程后就先于子进程之前退出了,所以它是一个由init接管的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出无论是向标准输出设备stdout还是标准出错设备stderr的输出都被丢到了/dev/null里。守护进程一般用作服务器进程,名称通常以d结尾,如sshd、httpd、syslogd等。

守护进程地特点

(1)运行方式:守护进程是Linux中的后台服务进程,它独立运行于后台、周期性地执行某种任务或等待处理某些发生的事件。

(2)生命周期:守护进程会长时间运行,常常在系统启动时就开始运行,直到系统关闭时才终止。

(3)守护进程不依赖于终端:一般来说,从终端开始运行地进程都会依附于终端,这个终端即为控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。我们平时写进程时,一个死循环程序关闭终端的同时也会关闭我们的程序,但是对于守护进程来说,其生命周期守护需要突破这种限制,它从开始运行,直到整个系统关闭时才会退出,所以守护进程不能依赖于终端。

守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户权限运行,因为它们要使用特殊的端口(1 ~ 1024)或访问某些特殊的资源。

创建守护进程的步骤:实现一个守护进程,其实就是将一个普通进程改造成具有守护进程特征的进程。

参考文章地址:https://blog.csdn.net/mijichui2153/article/details/81394387

(1)fork()创建子进程,父进程exit()退出。

(2)在子进程中调用setsid()创建新会话。

(3)再次fork()一个子进程,父进程exit()退出。

(4)在子进程中调用chdir()让根目录"/"成为子进程的工作目录。

(5)在子进程中调用umask()重设文件权限掩码为0。

(6)在子进程中close()掉不需要的文件描述符。

(7)守护进程退出处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 中,僵尸进程孤儿进程都是指与父进程不再有联系的进程,它们通常是由于进程管理不当或程序错误导致的。 **僵尸进程**是已经完成执行任务,但其父进程还没有来得及处理其退出状态的进程。当进程完成执行后,它的退出状态(也称为退出码或终止状态)会被保存在系统中,直到父进程通过 `wait` 或 `waitpid` 等函数来获取该状态。如果父进程没有处理该状态,那么该进程就会成为僵尸进程,占用系统资源。要清理僵尸进程,可以使用 `kill` 命令向其父进程发送 `SIGCHLD` 信号,或者重新编写程序,使其正确处理子进程的退出状态。 **孤儿进程**是指其父进程已经退出或被终止,但其自身仍在运行的进程。孤儿进程会被 `init` 进程(进程号为 `1`)接管,`init` 进程会定期检查系统中是否有孤儿进程,并且将其的父进程设置为 `init` 进程。要避免孤儿进程的产生,可以在父进程退出之前,等待子进程的退出,或者将子进程的父进程设置为 `init` 进程。 可以使用 `ps` 命令来查看系统中的僵尸进程孤儿进程。使用以下命令可以查看所有僵尸进程: ``` ps aux | grep 'Z' ``` 其中,`aux` 选项用于显示所有进程,`grep 'Z'` 用于查找所有状态为 `Z` 的进程,即僵尸进程。 使用以下命令可以查看所有孤儿进程: ``` ps -ejH ``` 其中,`-e` 选项用于显示所有进程,`-j` 选项用于以层次结构的形式显示进程,`-H` 选项用于显示所有孤儿进程

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值