• 01 / 进程退出
  • 02 / 孤儿进程
  • 03 / 僵尸进程
  • 04 / 进程回收
    • wait()函数
    • 退出信息相关宏函数
    • waitpid()函数

01 / 进程退出

//标准C库函数
#include <stdlib.h>
void exit(int status);//Linux系统函数
#include <unistd.h>
void _exit(int status);//status参数:是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。


示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {printf("hello\n");printf("world");// exit(0);_exit(0);return 0;
}

02 / 孤儿进程

父进程运行结束,但子进程还在运行(未运行结束),这样的子进程就称为孤儿进程(Orphan Process)。

◼ 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init 进程就会代表党和政府出面处理它的一切善后工作。

◼ 因此孤儿进程并不会有什么危害。

示例

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>int main() {// 创建子进程pid_t pid = fork();// 判断是父进程还是子进程if(pid > 0) {printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());} else if(pid == 0) {sleep(1);// 当前是子进程printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());}// for循环for(int i = 0; i < 3; i++) {printf("i : %d , pid : %d\n", i , getpid());}return 0;
}

03 / 僵尸进程

◼ 每个进程结束之后, 都会释放自己地址空间中的用户区数据,内核区的 PCB 没有办法自己释放掉,需要父进程去释放。

进程终止时,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。

僵尸进程不能被 kill -9 杀死这样就会导致一个问题,如果父进程不调用 wait() 或 waitpid() 的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程,此即为僵尸进程的危害,应当避免。

示例


04 / 进程回收

◼ 在每个进程退出的时候,内核释放该进程所有的资源、包括打开的文件、占用的内存等。但是仍然为其保留一定的信息,这些信息主要主要指进程控制块PCB的信息(包括进程号、退出状态、运行时间等)。

◼ 父进程可以通过调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

◼ wait() 和 waitpid() 函数的功能一样,区别在于,wait() 函数会阻塞,waitpid() 可以设置不阻塞,waitpid() 还可以指定等待哪个子进程结束。

◼ 注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

wait()函数
   #include <sys/types.h>#include <sys/wait.h>pid_t wait(int *wstatus);功能:等待任意一个子进程结束,如果任意一个子进程结束了,次函数会回收子进程的资源。参数:int *wstatus进程退出时的状态信息,传入的是一个int类型的地址,传出参数。返回值:- 成功:返回被回收的子进程的id- 失败:-1 (所有的子进程都结束,调用函数失败)调用wait函数的进程会被挂起(阻塞),直到它的一个子进程退出或者收到一个不能被忽略的信号时才被醒(相当于继续往下执行)如果没有子进程了,函数立刻返回,返回-1;如果子进程都已经结束了,也会立即返回,返回-1.
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 有一个父进程,创建5个子进程(兄弟)pid_t pid;// 创建5个子进程for(int i = 0; i < 5; i++) {pid = fork();if(pid == 0) {break;}}if(pid > 0) {// 父进程while(1) {printf("parent, pid = %d\n", getpid());// int ret = wait(NULL);int st;int ret = wait(&st);if(ret == -1) {break;}if(WIFEXITED(st)) {// 是不是正常退出printf("退出的状态码:%d\n", WEXITSTATUS(st));}if(WIFSIGNALED(st)) {// 是不是异常终止printf("被哪个信号干掉了:%d\n", WTERMSIG(st));}printf("child die, pid = %d\n", ret);sleep(1);}} else if (pid == 0){// 子进程while(1) {printf("child, pid = %d\n",getpid());    sleep(1);       }exit(0);}return 0; // exit(0)
}
退出信息相关宏函数
◼ WIFEXITED(status)  非0,进程正常退出
◼ WEXITSTATUS(status)   如果上宏为真,获取进程退出的状态(exit的参数)◼ WIFSIGNALED(status)     非0,进程异常终止
◼ WTERMSIG(status)      如果上宏为真,获取使进程终止的信号编号◼ WIFSTOPPED(status)  非0,进程处于暂停状态
◼ WSTOPSIG(status)      如果上宏为真,获取使进程暂停的信号的编号
◼ WIFCONTINUED(status)  非0,进程暂停后已经继续运行
waitpid()函数
    #include <sys/types.h>#include <sys/wait.h>pid_t waitpid(pid_t pid, int *wstatus, int options);功能:回收指定进程号的子进程,可以设置是否阻塞。参数:- pid:pid > 0 :   某个子进程的pidpid = 0 :   回收当前进程组的所有子进程    pid = -1 :  回收所有的子进程,相当于 wait()  (最常用)pid < -1 :  某个进程组的组id的绝对值,回收指定进程组中的子进程- options:设置阻塞或者非阻塞0 :         阻塞WNOHANG :   非阻塞- 返回值:> 0 :       返回子进程的id= 0 :       options=WNOHANG, 表示还有子进程或者= -1 :     错误,或者没有子进程了
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 有一个父进程,创建5个子进程(兄弟)pid_t pid;// 创建5个子进程for(int i = 0; i < 5; i++) {pid = fork();if(pid == 0) {break;}}if(pid > 0) {// 父进程while(1) {printf("parent, pid = %d\n", getpid());sleep(1);int st;// int ret = waitpid(-1, &st, 0);int ret = waitpid(-1, &st, WNOHANG);if(ret == -1) {break;} else if(ret == 0) {// 说明还有子进程存在continue;} else if(ret > 0) {if(WIFEXITED(st)) {// 是不是正常退出printf("退出的状态码:%d\n", WEXITSTATUS(st));}if(WIFSIGNALED(st)) {// 是不是异常终止printf("被哪个信号干掉了:%d\n", WTERMSIG(st));}printf("child die, pid = %d\n", ret);}}} else if (pid == 0){// 子进程while(1) {printf("child, pid = %d\n",getpid());    sleep(1);       }exit(0);}return 0;
}

【进程控制(进程退出、孤儿进程、僵尸进程)_Linux】相关推荐

  1. linux孤儿进程组深入理解,LInux下僵尸进程与孤儿进程是如何产生的?

    1:如何产生: 僵尸进程,先于父进程终止,但是父进程没有对其进行善后处理(获取终止子进程有关信息,释放它仍占有的资源).消灭僵尸进程的唯一方法是终止其父进程. 孤儿进程:该进程的父进程先于自身终止.其 ...

  2. linux 僵尸进程deffunc,多进程-开启子进程的两种方式,查看进程的pid与ppid,僵尸进程与孤儿进程...

    一.开启子进程的两种方式 方式一: # 方式一: from multiprocessing import Process import time def task(name): print(" ...

  3. 父进程为1号进程(ppid=1)的僵尸进程处理和分析

    在做稳定性测试时,发现某进程日志停了,也没有退出日志,也没有别的,就一顿操作,然后把进程搞成了僵尸进程 defunct .(疑似是 gdb attach 时,pkill -9 该线程了) 试着 kil ...

  4. linux 识别僵尸进程,Linux上寻找并杀死僵尸进程

    转载: http://blog.csdn.net/shanzhizi/article/details/47320595 linux服务器上,多少会出现一些僵尸进程,下面介绍如何快速寻找和消灭这些僵尸进 ...

  5. 进程的退出方式以及僵尸进程和孤儿进程

    (1)正常退出 (2)异常退出 检查wait和waitpid所返回的终止状态的宏 宏 说明 WIFEXITED(status) 若为正常终止子进程返回的状态,则为真.对于这种情况可执行WEXITSTA ...

  6. Linux 进程控制(创建/退出/等待/替换)

    目录 进程创建 fork()函数 fork返回值 fork写时拷贝 fork失败原因 fork用法 进程退出 退出场景 常见的退出方法 正常退出 异常退出 _exit()系统调用 exit()函数 _ ...

  7. python僵尸进程和孤儿进程_python中多进程应用及僵尸进程、孤儿进程

    一.python如何使用多进程 创建子进程的方式 1.导入multiprocessing 中的Process类 实例化这个类 指定要执行的任务 target import os from multip ...

  8. Linux进程3:父进程等待(wait,waitpid)子进程退出并收集子进程退出状态,僵尸进程

    父进程等待(wait,waitpid)子进程退出并收集子进程退出状态 1.父进程为什么要等待子进程退出? 创建子进程目的:------干活 我们要知道干活结束没. 子进程退出状态不被收集,变成僵尸进程 ...

  9. linux 进程 控制终端,linux系统编程之进程(五):终端、作业控制与守护进程

    #include#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while(0) int setup_daemon(int, int ...

  10. 进程之 回收子进程之避免僵尸进程的产生

    wait() 与 waitpid() 函数的使用. 因为前段时间博主没有把Windows系统带走所以不能实时更新博客,请见谅.接下来就让我们继续开始进程的世界吧. 前面我们说到了如何创建多个子进程那么 ...

最新文章

  1. JAVA网络编程:TCP/IP数据包结构
  2. Web服务器记录中查找***踪迹
  3. python写文件读文件-Python文件读写
  4. SpringBoot整合themeleaf+bootstrap (五)
  5. 数据结构之红黑树(三)——删除操作
  6. 分享一份 sublime 的个人配置文件
  7. Opencv3 Robert算子 Sobel算子 拉普拉斯算子 自定义卷积核——实现渐进模糊
  8. aswing学习笔记2-不规则外框-请教思路
  9. 一个小故事读懂Memcached漏洞
  10. 赶个项目,博客稍后更新
  11. 使用PHP官方镜像调用API进行文本翻译
  12. 报错 | Cannot find module ‘@better-scroll/core/dist/types/BScroll‘
  13. linux c语言math lm pow,C语言pow()函数实现求x的y次方的值
  14. Mysql DOS界面进入
  15. 第三章 代码的坏味道
  16. Unity快速入门之台球小游戏(二)
  17. CODEVS 2853 方格游戏
  18. Classification 分类学习
  19. 【YOLO】YOLO简介
  20. 服务器怎么修改mac地址怎么办,服务器修改mac地址重启后会恢復原mac吗?

热门文章

  1. win10共享打印错误0x0000006_win10系统局域网无法共享惠普打印机提示0x000006be错误的设置教程...
  2. 微软认证考试心得:微软认证考试的几种形式
  3. 吉他弹唱精通——4321进行
  4. python播放网络音乐_Python实现在线音乐播放器
  5. 利用python实现文件搜索功能
  6. 【莫比乌斯反演】互质数对
  7. C语言编程练习 1.按如下函数原型编写程序,用一个整型数组feedback保存调查的40个反馈意见。用函数编程计算反馈意见的平均数(Mean)、中位数(Median)和众数(Mode
  8. flutter 给icon图标添加阴影
  9. nginx 容错机制
  10. 在JavaScript中每5秒调用一个函数