当前位置: 首页 > news >正文

Linux中的特殊进程(孤儿进程、僵尸进程、守护进程)

一、孤儿进程

1)父进程退出,子进程不退出,此时子进程被1号(init)进程收养,变成孤儿进程。

2)孤儿进程会脱离终端控制,且运行在后端,不能用ctrl+c杀死后端进程,但是可以被kill -9杀死。

测试:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(int argc, const char *argv[])
{//父进程退出 子进程不退出pid_t cpid = fork();if(cpid > 0){}else if(0 == cpid){while(1)                                                      {printf("this is child %d %d\n", getppid(), getpid());sleep(1);}}else{perror("fork");return -1;}return 0;
}

二、僵尸进程

        子进程退出,父进程不退出去,且父进程没有给子进程收尸,此时子进程就变成僵尸进程。        

注意:

 1)僵尸进程只能被回收,不能被杀死。

 2)僵尸进程有危害:占用进程号,占用部分内存空间,占用物理空间,占用进程调度块(PCB)等等...

 3)回收僵尸进程的方式:

  • 退出父进程后,子进程的资源由内核自动回收。
  • wait / waitpid函数回收。缺点:阻塞函数,父进程无法做自己的事情。非阻塞形式,有可能收不到。
  • 结合信号的方式回收僵尸进程:当子进程退出后,通知父进程收尸。

测试:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(int argc, const char *argv[])
{//子进程退出,父进程不退出pid_t cpid = fork();if(0 == cpid){}else if(cpid > 0)                                        {while(1){printf("this is parent %d %d\n", getpid(), cpid);sleep(1);}}else{perror("fork");return -1;}return 0;
}

三、守护进程【幽灵进程】

  1. 守护进程脱离于终端,且运行在后端。
  2. 守护进程在执行过程中不会将信息显示在任何终端上,避免影响前端任务执行。且不会被任何终端产生的终端信息所打断。
  3. 守护进程目的:需要周期性执行某个任务或者周期性等待处理某些事情的时候,为了避免影响前端执行或者被前端信息打断的时候,可以使用守护进程。

守护进程的创建(5步):

  1. 创建孤儿进程:所有工作都在子进程中执行,从形式上脱离终端控制。
    fork(), 退出父进程
  2. 创建新的会话组:使子进程完全独立出来,防止兄弟进程对其有影响。
    setsid() 函数
    功能:创建一个新的进程组和会话组,成为该进程组和会话组组长;
    原型:#include <sys/types.h>#include <unistd.h>pid_t setsid(void);
  3. 修改当前孤儿进程的运行目录为不可卸载的文件系统:例如根目录,/tmp;防止运行目录被删除后,导致进程崩溃
    chdir函数
    功能:修改运行目录;#include <unistd.h>int chdir(const char *path);
    chdir("/");注意:从当前位置往后,运行在指定的目录下;
  4. 重设文件权限掩码:umask(0), 一般清零;
  5. 关闭所有文件描述符,从父进程继承过来的文件描述符不会用到,浪费资源。

代码:

 #include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <unistd.h>int main(int argc, const char *argv[]){//创建孤儿进程pid_t cpid = fork();if(0 == cpid){//创建新的回话pid_t sid =setsid();printf("sid = %d\n",sid);//修改运行目录为不可卸载的文件目录下chdir("/");//清空文件权限掩码umask(0);//关闭所有文件描述符for(int i = 0;i<getdtablesize();i++)close(i);while(1){//守护进程运行的周期性代码sleep(1);}}return 0;}

  • 输入ps ajx可查看进程之间的关系;
  • 输入pidof 文件名 可查看该文件是否有进程在运行;
  • 可通过 【kill -9 进程的pid号】将这个进程杀死;
  • 也可通过【killall -9 文件名】将该文件的所有在运行的进程杀死。
http://www.lryc.cn/news/107513.html

相关文章:

  • 【分布式能源选址与定容】光伏、储能双层优化配置接入配电网研究(Matlab代码实现)
  • 《cuda c编程权威指南》04 - 使用块和线程索引映射矩阵索引
  • mysql 、sql server 常见的区别
  • 查找特定元素——C++ 算法库(std::find_if)
  • D3JS教程_编程入门自学教程_菜鸟教程-免费教程分享
  • Android入门教程||Android 架构||Android 应用程序组件
  • C语言二进制数据和16进制字符串互转
  • 技术复盘(5)--git
  • GDAL C++ API 学习之路 (5) Spatial Reference System篇 OGRSpatialReference类
  • 2023年华数杯数学建模C题思路代码分析 - 母亲身心健康对婴儿成长的影响
  • WebAgent-基于大型语言模型的代理程序
  • 智慧~经典开源项目数字孪生智慧商场——开源工程及源码
  • LeetCode--剑指Offer75(1)
  • C++ 关于大端模式和小端模式的简析
  • 嵌入式:C高级 Day2
  • iPhone 7透明屏的显示效果怎么样?
  • 【C++】—— 多态常见的笔试和面试问题
  • 探寻AI大模型平台之巅——文心千帆
  • 【springboot】RestTemplate配置HttpClient连接池
  • MySQL内置函数使用说明
  • java后端富文本转word,再传递到浏览器下载。
  • 【动态规划算法】-回文串问题题型(34-40题)
  • STM32基础回顾
  • 如何解决电脑无声问题:排除故障的几种常见方法
  • Apache RocketMQ 命令注入
  • 二、搜索与图论6:Dijkstra 模板题+算法模板(Dijkstra求最短路 I, Dijkstra求最短路 II,1003 Emergency)
  • ROS2学习(四)进程,线程与节点的关系
  • 【物联网】DMA传输原理与实现详解(超详细)
  • Java类集框架(二)
  • 爬虫008_流程控制语句_if_if else_elif_for---python工作笔记026