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 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程的更多相关文章

  1. SpringBoot进阶教程(二十三)Linux部署Quartz

    在之前的一篇文章中<SpringBoot(九)定时任务Schedule>,已经详细介绍了关于schedule框架的配置和使用,有收到一些朋友关于部署的私信,所以抽时间整理一个linux部署 ...

  2. Linux 进程与信号的概念和操作

    进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 信号与进程几乎控制了操作系统的每个任务. 在shell中输 ...

  3. Linux 进程与信号的概念和操作 linux process and signals

    进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 译者:李秋豪 信号与进程几乎控制了操作系统的每个任务. 在 ...

  4. 三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数

    31.1 SIGCHLD 信号 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用 wait 调用来等待子进程结束并回收它. 避免僵尸进程 #include <stdio.h> # ...

  5. Linux 系统中僵尸进程

    Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸.配图源 ...

  6. Unix/Linux僵尸进程

    1. 僵尸进程的产生: 一个进程调用exit命令结束自己生命的时候,其实它并没有真正的被销毁,而是留下一个称为“僵尸进程”的数据结构.这时它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度 ...

  7. Linux 僵尸进程查杀

    僵尸进程概念 僵尸进程(Zombie process)通俗来说指那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸. 书面形式一点:一个进程结束了,但是他的父进程没有等待(调用wait ...

  8. Linux 网络编程详解六(多进程服务器僵尸进程解决方案)

    小结:在点对点p2p程序中,服务器端子程序退出,子进程会主动发送信号,关闭父进程,但是这种模式导致服务器只能支持一个客户端连接,本章节中使用新的框架,子进程退出,不主动发送信号关闭父进程,而是父进程安 ...

  9. linux僵尸进程产生的原因以及如何避免产生僵尸进程

    给进程设置僵尸状态的目的是维护子进程的信息,以便父进程在以后某个时间获取.这些信息包括子进程的进程ID.终止状态以及资源利用信息(CPU时间,内存使用量等等).如果一个进程终止,而该进程有子进程处于僵 ...

  10. Linux系统编程——特殊进程之僵尸进程

    僵尸进程(Zombie Process) 进程已执行结束,但进程的占用的资源未被回收.这种进程称为僵尸进程. 在每一个进程退出的时候,内核释放该进程全部的资源.包含打开的文件.占用的内存等. 可是仍然 ...

随机推荐

  1. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

  2. cf1000E We Need More Bosses (tarjan缩点+树的直径)

    题意:无向联通图,求一条最长的路径,路径长度定义为u到v必须经过的边的个数 如果把强联通分量都缩成一个点以后,每个点内部的边都是可替代的:而又因为这是个无向图,缩完点以后就是棵树,跑两遍dfs求直径即 ...

  3. centos7搭建ELK Cluster集群日志分析平台(三):Kibana

    续  centos7搭建ELK Cluster集群日志分析平台(一) 续  centos7搭建ELK Cluster集群日志分析平台(二) 已经安装好elasticsearch 5.4集群和logst ...

  4. Python中生成器generator和迭代器Iterator的使用方法

    一.生成器 1. 生成器的定义 把所需要值得计算方法储存起来,不会先直接生成数值,而是等到什么时候使用什么时候生成,每次生成一个,减少计算机占用内存空间 2. 生成器的创建方式 第一种只要把一个列表生 ...

  5. 编写高质量代码:改善Java程序的151个建议 --[52~64]

    编写高质量代码:改善Java程序的151个建议 --[52~64] 推荐使用String直接量赋值 Java为了避免在一个系统中大量产生String对象(为什么会大量产生,因为String字符串是程序 ...

  6. django跨域请求问题

    一 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之 ...

  7. 斯坦福大学公开课机器学习: machine learning system design | error analysis(误差分析:检验算法是否有高偏差和高方差)

    误差分析可以更系统地做出决定.如果你准备研究机器学习的东西或者构造机器学习应用程序,最好的实践方法不是建立一个非常复杂的系统.拥有多么复杂的变量,而是构建一个简单的算法.这样你可以很快地实现它.研究机 ...

  8. ubuntu vim01

    不小心按了ctrl+s(停止向终端输入),解决办法ctrl+q(恢复向终端输入)

  9. WebService 及 CXF 的进阶讲解

    4.2. WebService请求深入分析 1). 分析WebService的WSDL文档结构 1.1). 实例截图 <definitions> <types> <sch ...

  10. dubbox知识

    关于dubbox有以下小知识要注意: 1.传参数不能传List参数以及NULL,可以传""和0 2.不能传int类型 3.配置provider的时候,注意不要启动重连机制 < ...