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. iptables(1)

    iptables配置文件:/etc/sysconfig/iptables 确认开启路由转发功能方法1:/sbin/sysctl -w net.ipv4.ip_forward=1方法2:echo 1 & ...

  2. Visible Trees HDU - 2841(容斥)

    对于已经满足条件的(x1,y1),不满足条件的点就是(n*x1,n*y1),所以要求的就是满足点(x,y)的x,y互质,也就是gcd(x,y) == 1,然后就可以用之前多校的方法来做了 另f[i] ...

  3. 2018蓝桥杯 省赛D题(测试次数)

    x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机.各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通.x星球 ...

  4. request.getRequestDispatcher 页面跳转,样式丢失。

    在页面中引用样式和其它资源的时候,尽量不要用相对路径,因为"当前路径"这个概念在J2EE中是不稳定的. 所以最好都是绝对路径,类似于: <% String cp = requ ...

  5. Why I don't want use JPA anymore

    转自:https://dev.to/alagrede/why-i-dont-want-use-jpa-anymore-fl Great words for what is considered by ...

  6. ONI无法启动: Uh oh! Unable to launch Neovim...

    问题描述 在终端中是可以打开nvim的,ONI无法正确找到位置 解决方法 修改配置文件,指定nvim的路径 终端中输入which nvim定位所在位置,这里返回的结果是/usr/local/bin/n ...

  7. python中的单例模式、元类

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  8. 用popart构建常染色体单倍型网络(Autosomal haplotypes network construction with popart)

    1)将vcf转化为plink格式,假定输入的vcf文件名为:17893893-17898893.vcf,也可以参考链接:将vcf文件转化为plink格式并且保持phasing状态 /vcftools ...

  9. 【非专业前端】Vue UI 之 建立Vuetify工程

    先建立一个工程[Webpack] .. ..建立好之后,进入目录,添加vuetify插件 cd vuetify-demo vue add vuetify[会出错] npm install vuetif ...

  10. 在gitlab新建空项目,将本地的git仓库的内容上传

    gitlab新建了这个项目. 按照官网的步骤上传代码 一:将本地代码上传到本地仓库 1.进入项目文件夹 git init 2.项目代码添加到本地git git add . 3.提交到stage区域 g ...