二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程
23.1 进程链和进程扇
23.1.1 概念
进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程。。。。 这种就为进程链
进程扇:一个父进程构建出多个子进程,子进程都是由同一个父进程构建出来
  
23.1.2 进程链的构建
process_link.c
/* 创建5个进程(包括父进程) */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(int argc, char *argv[])
{
int counter = ; if(argc < ) {
counter = ;
} else {
counter = atoi(argv[]);
} int i = ;
pid_t pid; //循环变量从1开始,要减去父进程,即创建4个子进程
//需要保证父进程要跳出循环,子进程去创建子子进程
for(; i < counter; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
break; //父进程退出循环,子进程继续做循环
}
} printf("pid : %d, ppid: %d\n", getpid(), getppid());
while() {
sleep();
} return ;
}
运行:
  
执行 ps -ef | grep process_link 查看进程:
  
注意 8468 进程编号并不是 process_link 进程,它为 shell 的进程,运行的 process_link 的进程的父进程就是shell终端
23.1.3 进程扇的构建
/* 创建5个进程(包括父进程) */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(int argc, char *argv[])
{
int counter = ; if(argc < ) {
counter = ;
} else {
counter = atoi(argv[]);
} int i = ;
pid_t pid; //循环变量从1开始,要减去父进程,即创建4个子进程
//需要保证父进程要跳出循环,子进程去创建子子进程
for(; i < counter; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid == ) {
break; //子进程退出循环,父进程继续做循环
}
} printf("pid : %d, ppid: %d\n", getpid(), getppid());
while() {
sleep();
} return ;
}
编译运行如下,
  
子进程对应的父进程都为 113892
23.2 守护进程和孤儿进程
进程在操作系统中根据功能分为各种各样的进程。
23.2.1 守护进程
- 守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,在系统关闭时终止。
 - 所有守护进程都以超级用户(用户 ID 为0)的优先权运行
 - 守护进程没有控制终端
 - 守护进程的父进程都是 init 进程
 
23.2.2 孤儿进程
- 父进程结束,子进程就成为孤儿进程,会由 1 号进程(init 进程)领养
 
process_orphen.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(void)
{
pid_t pid; pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
printf("%d deaded\n", getpid());
exit();
} else {
sleep();
printf("pid : %d, ppid : %d\n", getpid(), getppid());
} return ;
}
编译运行:
  
这里由些奇怪的地方是孤儿进程被进程 2323领养,查看下这个进程:
  
这个进程的作用是:用于linux开机自动启动某些后台服务,同时还承担监控这些服务运行状态的功能。
这个进程代替了 1 号进程的一些特性,如果作死想试下关闭掉这个进程,可以进入下面的链接尝试:
https://www.cnblogs.com/chilumanxi/p/5136102.html
23.2.3 僵尸进程
- 子进程结束,但是没有完全释放内存(在内核中的 task_struct 没有释放),该进程就成为僵尸进程。
 - 当僵尸进程的父进程结束后,就会被 init 进程领养,最终被回收
 - 避免僵尸进程
- 让僵尸进程的父进程来回收,父进程每隔一段时间来查询子进程是否结束并回收,调用 wait() 或者 waitpid() ,通知内核释放僵尸进程
 - 采用信号 SIGCHLD 通知处理,并在信号处理程序中调用 wait 函数
 - 让僵尸进程成为孤儿进程,由 init 进程回收
 
 
(1)构建僵尸进程
process_zombie.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(void)
{
pid_t pid; pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid == ) {
printf("pid : %d, ppid: %d\n", getpid(), getppid());
exit(); //子进程结束成为僵尸进程
} while() {//父进程继续循环
sleep();
} exit();
}
编译运行:
  
另开一终端,查看进程

114707 为父进程,为S+,即可中断运行状态
子进程为 114708,状态为 Z+,Z即代表是僵尸进程,或者看进程名的 defunct ,有这个名字也为僵尸进程
二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程的更多相关文章
- SpringBoot进阶教程(二十三)Linux部署Quartz
		
在之前的一篇文章中<SpringBoot(九)定时任务Schedule>,已经详细介绍了关于schedule框架的配置和使用,有收到一些朋友关于部署的私信,所以抽时间整理一个linux部署 ...
 - Linux 进程与信号的概念和操作
		
进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 信号与进程几乎控制了操作系统的每个任务. 在shell中输 ...
 - Linux 进程与信号的概念和操作 linux process and signals
		
进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 译者:李秋豪 信号与进程几乎控制了操作系统的每个任务. 在 ...
 - 三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数
		
31.1 SIGCHLD 信号 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用 wait 调用来等待子进程结束并回收它. 避免僵尸进程 #include <stdio.h> # ...
 - Linux 系统中僵尸进程
		
Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸.配图源 ...
 - Unix/Linux僵尸进程
		
1. 僵尸进程的产生: 一个进程调用exit命令结束自己生命的时候,其实它并没有真正的被销毁,而是留下一个称为“僵尸进程”的数据结构.这时它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度 ...
 - Linux 僵尸进程查杀
		
僵尸进程概念 僵尸进程(Zombie process)通俗来说指那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸. 书面形式一点:一个进程结束了,但是他的父进程没有等待(调用wait ...
 - Linux 网络编程详解六(多进程服务器僵尸进程解决方案)
		
小结:在点对点p2p程序中,服务器端子程序退出,子进程会主动发送信号,关闭父进程,但是这种模式导致服务器只能支持一个客户端连接,本章节中使用新的框架,子进程退出,不主动发送信号关闭父进程,而是父进程安 ...
 - linux僵尸进程产生的原因以及如何避免产生僵尸进程
		
给进程设置僵尸状态的目的是维护子进程的信息,以便父进程在以后某个时间获取.这些信息包括子进程的进程ID.终止状态以及资源利用信息(CPU时间,内存使用量等等).如果一个进程终止,而该进程有子进程处于僵 ...
 - Linux系统编程——特殊进程之僵尸进程
		
僵尸进程(Zombie Process) 进程已执行结束,但进程的占用的资源未被回收.这种进程称为僵尸进程. 在每一个进程退出的时候,内核释放该进程全部的资源.包含打开的文件.占用的内存等. 可是仍然 ...
 
随机推荐
- 【mysql】mysql  null值
			
在数据表我们有时候有些表字段会为null,表示空.其实在mysql中null值是占用空间的. mysql手册如下解释 NULL columns require additional space in ...
 - OnCheckedChangeListener和setChecked之间冲突问题解决
			
判断是否点击!buttonView.isPressed()来解决 CompoundButton.OnCheckedChangeListener checkedChangeListener = new ...
 - spring activemq 整合
			
创建maven项目 项目目录结构为 首先配置相关maven依赖 <!-- 版本管理 --> <properties> <springframework>4.1.8. ...
 - jquery 追加元素/jquery文档处理,插入、修改、移动、删除指定的DOM元素.
			
jquery 追加元素 $("#content").append("..."); // 添加到元素内部最后面 $("#content").p ...
 - vue $emit 用法
			
1.父组件可以用props传递给子组件. 2.子组件可以利用$emit触发父组件事件. vm.$emit('父组件方法',参数); vm.$on(event,fn); $on监听event事件后运行f ...
 - C# Winform多窗体&&构造函数传值
			
一.多窗体:三种打开窗体的状态: 最最基础的弹窗: //写在按钮的点击事件内: //实例需要弹出的窗口的类: Form2 f2 = new Form2(); f2.Show(); 1.弹窗窗口: // ...
 - Can not issue data manipulation statements with executeQuery()错误解决
			
转: Can not issue data manipulation statements with executeQuery()错误解决 2012年03月27日 15:47:52 katalya 阅 ...
 - Filter(过滤器)
			
一.Filter过滤器(重要) Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作. 1.Filter快速入门 1.1.步骤: 1. 创建一个类实现Filter接口 2. 重写接口中方 ...
 - java中Comparatable接口和Comparator接口的区别
			
1.不同类型的排序规则 .自然排序是什么? 自然排序是一种升序排序.对于不同的数据类型,升序规则不一样: BigDecimal BigInteger Byte Double Float Int ...
 - SSH框架下ajax调用action并生成JSON再传递到客户端【以get和post方式提交】
			
需要完成的任务: 主要是把JSP页面上图片ID传给服务器端,服务器读取cookie看是否有username,如果有则根据ID读取MongoDB数据库,读出图片URL,再存放到mysql中的collec ...