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

Linux系统编程-进程及相关指令与函数

目录

一. 进程

1.1 什么是进程

进程:

程序:

1.2 进程的创建过程

1.3 进程的调度

并发:

CPU任务调度算法:

1.4 进程的状态

三态图

Linux进程状态:

二. 进程相关的指令

2.1 ps aux

2.2 ps -ef

2.3 pstree

2.4 kill

2.5 fg

三. 进程控制函数

3.1 fork

3.2 getpid与getppid

3.3 孤儿进程

3.4 僵尸进程

四. 进程的退出与消亡

4.1 进程的退出

4.2 如何避免僵尸进程:

一. 进程

单任务:程序运行起来,只能处理一件事情

多任务:程序运行起来,可以处理多件事情

1.1 什么是进程

进程:

进程:进程就是运行起来的程序,需要分配CPU资源与内存,多进程之间有资源的竞争

进程是一个动态的过程,具有生命周期

进程可以实现并发(多任务)

进程是操作系统分配资源的最小单位

程序:

程序:存放在硬盘的数据指令集合

静态的

程序运行起来可以创建多个进程

1.2 进程的创建过程

在创建进程时,操作系统会为其分配0~4G的虚拟内存地址空间

1.3 进程的调度

总结一句话:宏观并行,微观串行

宏观上多个任务同时进行,微观上多个任务按照一定的顺序执行

并发:

并发:在操作系统中,一个时间段内,有多个进程处于已启动运行到运行结束状态之间,但是同一时间点上,只有一个进程在运行

CPU任务调度算法:

1、时间片轮询

2、先来先服务,后来后服务

3、优先级高者先服务,优先级低者后服务

4、短作业优先

1.4 进程的状态

任何操作系统的进程切换图:

三态图

Linux操作系统的进程切换图:

Linux进程状态:

运行态(用户运行态,内核运行态) R正在被CPU任务调度所执行的进程
就绪态R正在执行,但是没有被CPU任务调度的进程
可唤醒等待态 S也称为睡眠态,阻塞等待资源的进程
不可唤醒等待态 D不想被CPU任务调度打断的进程任务,可设置不可唤醒等待状态
暂停态 T被暂停执行过程
僵尸态 Z进程执行结束,资源没有被回收
结束态 X进程执行结束,空间被回收

二. 进程相关的指令

2.1 ps aux

作用:查看操作系统中进程相关的信息

注意:1号进程为init进程,作用:是系统的起点,收养孤儿进程,清理僵尸进程等

USER用户
PID进程ID
%CPU %MEM进程对CPU,内存的占有率
VSZ RSS内存相关信息
TTY对终端的使用(?表示没有使用终端)
STAT进程状态
START TIME进程开始的日期和时间
COMMAND进程名称

2.2 ps -ef

作用:查看进程信息,可以查看进程ID与其父进程ID

2.3 pstree

作用:查看进程间的创建关系 加上选项-p可以显示进程ID

2.4 kill

作用:给指定PID的进程发送指定的信号:kill -信号编号/信号名称 PID

信号:可以使用命令kill -l来查看信号的种类及其信号编号

9号SIGKILL:结束指定的进程

19号SIGSTOP:暂停指定的进程

18号SIGCONT:继续指定的进程

2.5 fg

作用:将指定的进程由后台调至前台

使用方法:fg 进程编号

获取进程编号:指令jobs,作用:获取当前终端的后台进程及其编号

三. 进程控制函数

3.1 fork

关键在于duplicating

作用:创建一个子进程

返回值:>0:表示在父进程中返回子进程的PID

=0:表示当前处于子进程中

<0:出错并且设置errno

注意:1、子进程完全拷贝父进程的0~3G进程地址空间(用户空间:堆区,栈区,文本区,数据区

等)

2、但是对内核区的拷贝不完全,比如PCB中的PID号就不一样,但是又拷贝了文件描述符

3、父子进程之间数据不共享,要想通信就得使用进程间通信方式

可以使用下面一段代码来验证:

//int num = 100;全局变量不共享 int main() { //int num = 300;//局部变量也不共享 int *pnum = malloc(sizeof(int));//堆区资源也不共享 if(pnum == NULL){ perror("malloc()"); return -1; } *pnum = 600; pid_t pid = fork(); if(pid < 0){ perror("fork()"); return -1; } else if(pid > 0){ while(1){ printf("---parent: my pid is %d,my parent pid is %d, num = %d\n", getpid(), getppid(), *pnum); sleep(1); } } else{ //num = 200; *pnum = 900; while(1){ printf("-----child: my pid is %d,my parent pid is %d, num = %d\n", getpid(), getppid(), *pnum); sleep(1); } } return 0; }

这里有一个小栗子:

问下面这个程序总共可以fork出几个进程?

int main() { fork() && fork() || fork(); getchar(); return 0; }

结果:使用pstree -sp 进程ID查看:可以看出总共有五个进程

这里需要注意&&||操作符的短路效应

表达式1 && 表达式2 || 表达式3 这条语句如果表达式1是假,那么后面是不是就都不执行了?不是这样的:表达式1为假,只能短路掉表达式2,|| 左边整体为假,故表达式3仍要执行。

3.2 getpid与getppid

作用:获取当前进程的pid当前进程的父进程的pid

3.3 孤儿进程

父进程先于子进程结束,则此子进程成为孤儿进程,则这个子进程的父进程变成了一个系统进程,在早期的操作系统中,孤儿进程直接被1号进程init进程收养,但是init进程的任务繁重,后来又重新封装了一个进程组来回收孤儿进程

孤儿进程的用处:后台的守护进程

可以使用下面的代码来观察孤儿进程:

int main() { pid_t pid = fork(); if(pid > 0){ printf("parent:pid is %d, child is %d\n",getpid(),pid); sleep(10);//父进程10s后死亡,子进程成为孤儿进程 } else if(pid == 0){ while(1){//子进程循环打印 printf("child:pid is %d, parent is %d\n",getpid(),getppid()); sleep(1); } } return 0; }

结果:在父进程结束后,子进程的父进程成为了1495这个进程

3.4 僵尸进程

子进程结束后,父进程没有回收子进程残留在内核空间中的资源(PCB),导致该子进程变成了僵尸进程。

注:子进程结束后,其用户空间的所有资源默认由操作系统回收,但是内核空间的PCB还残留在内核中,原因:PCB记录了子进程退出的原因,若是正常退出则保存其退出状态,若是异常退出,则保存使其异常退出的原因,比如信号等等,父进程可以调用wait或者waitpid来获取这些信息,然后彻底清除掉这个进程残留的资源。

使用kill -9命令无法使僵尸进程结束,只能将其父进程结束,然后该子进程成为孤儿进程,然后被收养和回收

使用这段代码可以观察到僵尸进程这个状态:

int main() { pid_t pid = fork(); if(pid > 0){ while(1){ printf("parent:pid is %d, child is %d\n",getpid(),pid); sleep(1);//父进程一直在打印,没有回收子进程,则子进程变成僵尸进程 } } else if(pid == 0){ printf("child:pid is %d, parent is %d\n",getpid(),getppid()); sleep(10);//子进程10s后结束 printf("child die\n"); } return 0; }

结果:

10s前:

10s后:可以看到子进程变成了僵尸进程Z+

四. 进程的退出与消亡

4.1 进程的退出


1. 在主函数中return
2.exit(),库函数,直接结束一个进程,结束前会刷新缓冲区
3._exit(),_Exit(),系统调用,直接结束一个进程,结束前不会刷新缓冲


4.2 如何避免僵尸进程:


1. 子进程结束,由其父进程回收资源空间
2. 让子进程成为一个孤儿进程

http://www.jsqmd.com/news/951145/

相关文章:

  • 微信小程序语音跟读练习功能源码(含录音、波形对比、语音识别与播放)
  • 雪糕棍机械臂DIY:Arduino入门机器人项目全解析
  • 告别重复点击:如何用自动化脚本解放你的星穹铁道游戏时间
  • WenQuanYi Micro Hei 深度解析:5MB超轻量级中文字体的企业级部署与性能优化指南
  • Illustrator画板智能同步缩放:告别手动调整的终极解决方案
  • 轴流风机哪家好常见问题解答(2026最新专家版) - 资讯纵览
  • Python自动化抢票终极指南:300行代码实现大麦网秒杀系统
  • Ubuntu 20.04上编译OpenFOAM v2006完整避坑指南:从依赖安装到算例验证
  • DIY情绪灯:从电路原理到创意制作的入门电子项目
  • 百度网盘提取码终极解决方案:如何3秒破解资源访问难题
  • SpringBoot2.3+项目里,Lettuce连接Redis集群老断线?手把手教你配置拓扑自动刷新
  • Java实战:手把手教你搞定收钱吧轻POS接口的RSA签名与回调(附完整代码)
  • 2026 宿迁卫生间漏水、外墙、楼顶、地下室、阳光房渗漏维修师傅推荐|同城附近上门防水补漏公司测评 - 企业资讯
  • 从Ridge到Lasso:一次搞懂正则化,用真实金融数据看它们如何影响你的预测模型
  • ArcGIS制图笔记:手把手教你设置‘温克尔三重投影’,让世界地图的中央经线穿过你家
  • Horos:macOS上免费的医学影像查看器终极指南,5个实用技巧让你快速上手
  • Arduino密码锁保险箱制作教程:从嵌入式编程到机械结构完整实现
  • Kali Linux安装后必做的5件事:从配置APT源到更新工具库(2024最新)
  • GPT-5.5 Nano实战指南:轻量模型如何驱动企业级AI落地
  • 从零设计环境光控LED电路:模拟方案全流程实战指南
  • 基于树莓派的智能加湿器项目:从硬件选型到软件部署的物联网实践
  • Argo浮标数据能告诉我们什么?用Python拆解海平面上升中的‘温度贡献’与‘盐度贡献’
  • Windows上安装APK文件的最佳解决方案:APK-Installer全面指南
  • ImageToSTL:将平面图像转换为可打印立体模型的开源解决方案
  • 硬件元器件简单学学(TODO)
  • 告别软解卡顿:用GStreamer的nvdec插件在Ubuntu上实现4K视频硬解播放(附VLC/自定义播放器集成指南)
  • 2026 抖店一键下单平台服务软件怎么选?拍单工具系统品牌选型对比推荐 - 资讯纵览
  • AI产品经理 vs 传统产品经理:4大区别+4大相同点,面试必考!
  • 在快马上快速搭建你的第一个langgraph智能体工作流原型
  • 新手入门指南:借助快马AI从零理解网络测试工具箱的开发原理