二十三、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) 进程已执行结束,但进程的占用的资源未被回收.这种进程称为僵尸进程. 在每一个进程退出的时候,内核释放该进程全部的资源.包含打开的文件.占用的内存等. 可是仍然 ...
随机推荐
- Centos7之Gcc安装
1下载Gcc包进行安装https://gcc.gnu.org 下载下来的是一个包文件,但是要进行一系列的编译安装,听麻烦的. 不如直接使用这个yum来从网络上进行安装. 2 yumyum instal ...
- Distinct Values(2018hdu多校第一场)
给你一段长度为n的区间,然后在给你m个小区间,要求这m个小区间里的每个人都不能重复,请你输出字典序最小的方案. 我们可以开一个suf数组,表示我到我后面的不出现重复数字的区间至少需要到达的位置.所以对 ...
- Mysql 从入门到遗忘
高级数据过滤: WHERE AND OR NOT 总是与其他操作符一起使用,用在要过滤的前面. 通配符过滤: LIKE: %相当于正则中的.*?,_相当于正则中的.. $ select id from ...
- JVM内存模型你只要看这一篇就够了
JVM内存模型你只要看这一篇就够了 我是一只孤傲的鱼鹰 让我们不厌其烦的从内存模型开始说起:作为一般人需要了解到的,JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这 ...
- Go实战--golang中使用JWT(JSON Web Token)
http://blog.csdn.net/wangshubo1989/article/details/74529333 之前写过关于golang中如何使用cookie的博客: 实战–go中使用cook ...
- git的使用命令
git archive --format zip --output "./test.zip" master -0 将项目的代码通过上述命令打包压缩为test文件夹 ssh-keyg ...
- Django(十一)请求生命周期之CBV与FBV
https://www.cnblogs.com/yuanchenqi/articles/8715364.html FBV FBV(function base views) 就是在视图里使用函数处理请求 ...
- 【译】2. Java反射——Class对象
原文地址:http://tutorials.jenkov.com/java-reflection/classes.html ====================================== ...
- hdu 4283"You Are the One"(区间DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题意: 有n个屌丝排成一排,每个屌丝都有一个不开心值a[ i ]( i=1,2,3,.. ...
- Linux sys_call_table变动检测
catalogue . 引言 . 内核ko timer定时器,检测sys_call_table adress变动 . 通过/dev/kmem获取IDT adress . 比较原始的系统调用地址和当前内 ...