Linux系统编程34 进程控制 - init 进程和僵死进程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Linux系统编程34 进程控制 - init 进程和僵死进程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4773字,纯文字阅读大概需要7分钟。
内容图文
如下程序,即 fork()求质数 改动:
实验1 父进程不睡眠,201个子进程睡眠
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#define LEFT 200
#define RIGHT 250
int main(void)
{
int i,j,mark;
pid_t pid;
for(i = LEFT; i <= RIGHT; i++)
{
pid = fork();
if(pid < 0)
{
fprintf(stderr,"fork() failed!\n");
exit(1);
}
else if(pid == 0)//child
{
mark = 1;
for(j = 2; j < i/2; j++)
{
if(i % j ==0)
{
mark = 0;
break;
}
}
if(mark)
printf("%d is a primer\n",i);
sleep(1000);
exit(0);//!!!
}
}
exit(0);
}
改动:每个子进程结束前 睡眠1000秒,这样的话 父进程一定是先结束,而201个子子进程后结束。这种情况 父进程创建201个子进程后就直接 exit()结束了,而子进程干完活就 sleep了。
ps axf 查看进程状态:
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axf
15800 pts/2 S 0:00 \_ ./a.out
15801 pts/2 S 0:00 \_ ./a.out
15802 pts/2 S 0:00 \_ ./a.out
15803 pts/2 S 0:00 \_ ./a.out
15804 pts/2 S 0:00 \_ ./a.out
15805 pts/2 S 0:00 \_ ./a.out
15806 pts/2 S 0:00 \_ ./a.out
15807 pts/2 S 0:00 \_ ./a.out
15808 pts/2 S 0:00 \_ ./a.out
15809 pts/2 S 0:00 \_ ./a.out
15810 pts/2 S 0:00 \_ ./a.out
15811 pts/2 S 0:00 \_ ./a.out
15812 pts/2 S 0:00 \_ ./a.out
15813 pts/2 S 0:00 \_ ./a.out
15814 pts/2 S 0:00 \_ ./a.out
15815 pts/2 S 0:00 \_ ./a.out
15816 pts/2 S 0:00 \_ ./a.out
15817 pts/2 S 0:00 \_ ./a.out
15818 pts/2 S 0:00 \_ ./a.out
15819 pts/2 S 0:00 \_ ./a.out
15820 pts/2 S 0:00 \_ ./a.out
...
...
...
可以看到 201个子进程全部是顶格写的,故 201进程的父进程是 init进程
对于父进程已经终止的所有进程,它们的父进程都改变为 init 进程,我们称 这些进程由 init进程收养。其操作过程大致是: 在一个进程A终止时,内核会逐个检查所有其他的活动进程 B C D…等等,来判断这些活动进程 是不是终止进程A 的子进程,如果是的话,则活动进程的父进程更改为1(init 进程的ID 为1),这种处理方法保证了每一个进程都有一个父进程。
实验2 父进程睡眠,子进程不睡眠
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#define LEFT 200
#define RIGHT 250
int main(void)
{
int i,j,mark;
pid_t pid;
for(i = LEFT; i <= RIGHT; i++)
{
pid = fork();
if(pid < 0)
{
fprintf(stderr,"fork() failed!\n");
exit(1);
}
else if(pid == 0)//child
{
mark = 1;
for(j = 2; j < i/2; j++)
{
if(i % j ==0)
{
mark = 0;
break;
}
}
if(mark)
printf("%d is a primer\n",i);
exit(0);//!!!
}
}
sleep(1000);
exit(0);
}
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axf
\_ zeitgeist-datahub
2824 ? Sl 0:37 \_ /usr/bin/python /usr/bin/terminator
2836 ? S 0:00 | \_ gnome-pty-helper
2837 pts/0 Ss 0:01 | \_ /bin/bash
16001 pts/0 R+ 0:00 | | \_ ps axf
2858 pts/2 Ss 0:00 | \_ /bin/bash
15944 pts/2 S+ 0:00 | \_ ./a.out
15945 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15946 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15947 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15948 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15949 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15950 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15951 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15952 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15953 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15954 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15955 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15956 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15957 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
15958 pts/2 Z+ 0:00 | \_ [a.out] <defunct>
...
....
....
3692 ? Sl 0:02 \_ /usr/lib/x86_64-linux-gnu/notify-osd
本实验,由于父进程没有退出,故所有的子进程的 父进程依然是 之前的父进程,并没有转交给 init进程。
可以看到 此时的201个子进程 的进程状态为 Z+ 即 zombie 僵尸进程。那么什么是僵尸进程,僵尸进程是如何产生的?
在UNIX术语中,一个已经终止,但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍然占用的资源)的进程成为 僵尸进程。
所以 对于上述例子,父进程fork了201个子进程,除非父进程等待获取子进程的终止状态,否则这些子进程终止后就会变成僵尸进程,如上。关于如果对子进程进行善后处置,用 wait()/waitpid() 处理,下节详细说明。
还有一个注意事项,一个由 init 进程收养的进程终止的时候会发生什么?他会不会变成一个僵尸进程?
答案是否定的,init进程被设计成 无论何时 只要有一个子进程终止, init就会调用一个 wait() 函数对其进行善后处理,获取其终止状态。这样就防止了系统中塞满僵尸进程。
内容总结
以上是互联网集市为您收集整理的Linux系统编程34 进程控制 - init 进程和僵死进程全部内容,希望文章能够帮你解决Linux系统编程34 进程控制 - init 进程和僵死进程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。