【Linux】僵尸进程和孤儿进程
来源:互联网 发布:marginnote windows版 编辑:程序博客网 时间:2024/06/05 19:51
在我们进行关于僵尸进程和孤儿进程的分析前,先了解下进程都有哪些状态:
下面的状态在 fs/proc/array.c 文件里定义:
/** The task state array is a strange "bitmap" of* reasons to sleep. Thus "running" is zero, and* you can test for combinations of others with* simple bit tests.*/static const char * const task_state_array[] = {"R (running)", /* 0 */"S (sleeping)", /* 1 */"D (disk sleep)", /* 2 */"T (stopped)", /* 4 */"t (tracing stop)", /* 8 */"X (dead)", /* 16 */"Z (zombie)", /* 32 */};
R : running ,运行状态 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
S :sleeping ,睡眠状态 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。需要强调的是此时进程并不是什么都不做,它执行了休眠代码,是可以被杀死的。
D :disk sleep ,,磁盘休眠状态 也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。与 S 相反,它是不可以被杀死的,中断它的方法只能是系统关机修复重启,或者“主动醒来”。
T :stopped ,终止状态 此时进程不做任何事。
t :tracing stop ,跟踪终止状态 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
例如,可以用下面的方法来停止或继续运行进程:
kill -SIGSTOP <pid> 进程状态从 R 到 T
kill -SIGCONT <pid> 进程状态从 T 到 R
可以使用 gdb 终止进程来实现跟踪终止状态。
X :dead ,死亡状态 是内核运行 kernel/exit.c 里的 do_exit() 函数返回的状态。这个状态只是一个返回状态,不会在任务列表里看到这个状态。
Z :Zombie ,僵死状态 当进程退出并且父进程(使用 wait() 系统调用)没有读取到子进程退出的返回代码时就会产生僵死进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
以上就是进程的状态分类,下面我们具体对僵尸进程和孤儿进程做以讨论。
僵尸进程:一个子进程在其父进程没有调用 wait() 或 waitpid() 的情况下退出。这个子进程就是僵尸进程。如果其父进程还存在而一直不调用 wait ,则该僵尸进程将无法回收,等到其父进程退出后该进程将被 init 回收。
我们来创建一个维持30秒的僵死进程例子:
运行 ./myenv 时我们会发现先打印出来子进程的内容,即子进程先退出,30秒后父进程的内容才被打印,此时可以证明进程从子进程运行到父进程运行的中间时间段30秒,进程是处于僵死状态的,这样的子进程就是僵尸进程。
如果你不是很清楚父子进程分别为哪个的话,我们可以通过父子进程的 PID 验证一下这两者的关系。
同样地,我们在 env.c 中编写代码,然后调试、运行,观察分析结果。
其实只要不按下 Ctrl+C ,我们会发现程序一直在运行,不会停止,而且我们能够很清楚地看到只有一行的子进程 child ,它的 PID 是7855,PPID 即父进程是7854,我想这样表述你是不是就很清楚父子进程了呢,那么有人可能会疑惑5124是什么呢,很简单,对父进程 father 来说,它自己的 PID 是7854,它的父进程是 bash ,PPID 的值就是5124。
上面的图片是我用 ps -l 命令查看的优先级信息,我们会看到 bash 的 PID 就是5124,其余的暂时不做讨论。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为1)所收养,并由 init 进程对它们完成状态收集工作。
下面我们来创建一个孤儿进程的例子:
关于如何一步步创建的步骤,此处不再赘述,同上。
我们可以发现父进程先运行输出,休眠一秒后子进程运行,打印出来 pid 为 8533 ,ppid 为 8532 ,然后子进程休眠五秒,父进程运行结束后退出,此时父进程不会接收它,所以它会一直等待直到 init 进程收集它时才停止整个进程,上述的 init 即为 1 。可以证明无父进程接收的子进程就是孤儿进程。
这就是我对于僵尸进程和孤儿进程的理解,中间穿插了一些关于父子进程的知识,希望能够对你理解这两个进程有所帮助。
- linux下僵尸进程和孤儿进程
- Linux中的 僵尸进程 和 孤儿进程
- linux 僵尸(defunct)进程和孤儿进程
- Linux中的 僵尸进程 和 孤儿进程
- linux 孤儿进程和僵尸进程
- Linux中的 僵尸进程 和 孤儿进程
- 【Linux编程】僵尸进程和孤儿进程
- 【Linux】僵尸进程和孤儿进程
- linux下孤儿进程和僵尸进程
- Linux中的僵尸进程和孤儿进程
- Linux — 孤儿进程和僵尸进程
- linux僵尸进程和孤儿进程
- 孤儿和僵尸进程
- Linux 僵尸进程 孤儿进程
- 孤儿进程和僵尸进程
- 僵尸进程和孤儿进程
- 孤儿进程和僵尸进程
- 孤儿进程和僵尸进程
- 分治画分形图 之 谢尔宾斯基三角形
- Microsoft visio 2010 Premium 的激活
- android6.0以上版本蓝牙4.0开发
- JAVA RGB转CMYK 源码(支持格式转换)
- Mysql中的sql server 与mysql 与orcle与acess与sql与mssql大体了解
- 【Linux】僵尸进程和孤儿进程
- LightOJ 1282 Leading and Trailing
- Java基础之Socket编程
- php中$this->是什么意思
- 如何在 BroadcastReceiver 中执行耗时操作?
- xib中User Defined Runtime Attributes使用
- 【Python-matplotlib】subplot2grid()函数的简单示例
- CPP复习笔记 1
- idea2016_64bit 控制台输出中文乱码