Linux应用软件编程03-进程

发布时间:2026/11/5 2:17:34

Linux应用软件编程03-进程 一、进程介绍1.1 进程相关概念① 单任务和多任务单任务程序运行起来只能处理一件事情多任务程序运行起来可以处理多件事情②进程正在执行的程序执行过程中需要消耗CPU和内存是程序动态执行的过程包括创建、调度、消亡。③ 进程是操作系统资源分配的最小单位。④ 程序和进程的区别程序存放在硬盘的数据指令集合静态的程序运行起来时可以创建出多个进程进程进程是一个正在执行的程序在内存中执行指令进程是一个动态的过程具备一定的生命周期进程可以实现并发多任务执行过程中需要消耗CPU和内存多进程间存在资源竞争1.2 进程的创建过程① 在创建进程时32位操作系统下操作系统会为其分配0~4G的虚拟内存地址空间②虚拟地址空间32 位系统4GB2^3264 位系统16EB2^64实际通常用 48 位 256TB③进程空间特性进程空间是独立的每个进程独享进程空间。所有进程共享 0-4G 虚拟内存。分时复用同一虚拟空间不同进程数据不重叠。MMU 内存映射单元将虚拟地址空间映射为实际的物理空间1.3 进程的调度①宏观并行从宏观角度多个任务同时执行②微观串行微观角度多个任务按照一定顺序先后执行③ 多个进程任务需要同时运行。④常见CPU进程调度算法先来先执行后来后执行短作业优先算法高优先级调度算法时间片轮转调度算法宏观并行微观串行多级队列反馈调度算法负载均衡调度算法⑤并发在操作系统中一个时间段内有多个进程处于已启动运行到运行结束状态之间但是同一时间点上只有一个进程在运行⑥ 时间片CPU在进程任务中执行的一小段时间称为时间片1.4 进程的状态① 任何操作系统进程状态切换图三态图② Linux操作系统进程状态切换③ Linux进程状态状态简称状态名称描述R运行态(用户运行态、内核运行态)正在被CPU任务调度所执行的进程R就绪态没有被CPU轮转到的正在执行的任务只缺少cpuS可唤醒等待态睡眠态进程因等待资源如I/O操作而阻塞但可被信号或其他事件唤醒D不可唤醒等待态进程处于深度睡眠状态不可被信号或事件中断通常用于关键资源等待场景T暂停态进程因接收外部信号例如SIGSTOP而被暂停执行此时操作系统将其状态切换为停止态。Z僵尸态进程已终止但其资源如进程描述符未被父进程回收X结束态进程完全终止资源已被系统回收1.5 进程的退出和消亡① 进程执行结束需要对进程对应的资源空间进行回收否则该进程进入僵尸态。②进程退出在主函数中returnexit库函数直接结束一个进程,结束前会刷新缓冲区_exit(), _Exit()系统调用直接结束一个进程,结束前不会刷新缓冲区调用_exit(), _Exit()函数会清除其使用的内存空间并销毁其在内核中的各种数据结构关闭进程的所有文件描述符并结束进程、将控制权交给操作系统。被动退出异常退出、使用signal结束一个进程kill③进程的消亡1僵尸进程产生原因进程代码执行结束空间没有被回收就会成为僵尸进程2如何避免产生僵尸进程让父进程先结束子进程称为孤儿进程被init进程收养子进程结束 init进程回收子进程空间避免产生僵尸进程子进程结束父进程回收子进程空间就能避免子进程称为僵尸进程④孤儿进程 父进程先结束其父进程创建的子进程成为孤儿进程将会被系统进程收养结束时由系统进程回收二、进程相关的指令2.1ps -aux作用显示操作系统中所有进程的详细信息。注意1号进程为init进程作用是系统的起点收养孤儿进程清理僵尸进程等ps -aux | grep a.out| 管道 将前面的命令的输出作为后面命令的输入grep 搜索包含指定字符串此处为a.out的文本信息USER用户PID进程ID%CPU %MEM进程对CPU内存的占有率VSZ RSS内存相关信息TTY对终端的使用(?表示没有使用终端)STAT进程状态START TIME进程开始的日期和时间COMMAND进程名称2.2 top作用动态查看进程的相关参数侧重于CPU和内存占有率q 退出。PID唯一区分进程的ID号。PPID父进程的ID号。%Cpu(s) 行CPU整体占用统计字段含义 截图里的实际值解释us用户态进程占用CPU时间比例这里是0.2%说明普通用户程序几乎没占CPUsy内核态占用CPU时间比例这里0.5%系统内核开销极低ni调整过nice优先级的用户进程占用比例这里0.0%idCPU空闲比例这里99.3%说明当前系统CPU非常空闲几乎没有压力waIO等待占用CPU的比例这里0.0%说明磁盘/网络IO完全没有拖慢CPUhi硬件中断处理占用比例0.0%si软件中断处理占用比例0.0%st虚拟化环境下被宿主机偷走的CPU时间0.0%物理机运行无损耗KiB Mem 行物理内存统计单位是KB字段含义 实际值解释total总物理内存1999388KB ≈ 2GBfree完全空闲的内存92704KB ≈ 90MBused进程和系统已经使用的内存1485672KB ≈ 1.4GBbuff/cache内核用于文件缓存、页缓存的内存421012KB ≈ 410MB这部分内存是可以随时释放给应用程序用的KiB Swap 行交换分区统计交换分区是把硬盘空间临时当内存用的扩容机制字段含义 实际值解释total交换分区总大小1999868KB ≈ 2GBfree交换分区空闲大小811400KB ≈ 792MBused交换分区已使用大小1188468KB ≈ 1.13GBavail Mem系统实际可用内存空闲内存可回收的缓存326420KB ≈ 318MB每个运行进程的详细状态字段含义 截图示例说明PID进程ID系统里每个进程的唯一数字标识比如截图里Xorg的PID是1787USER进程的运行用户比如Xorg是linux用户运行systemd是root用户运行PR进程的调度优先级数值越小优先级越高截图里大部分进程PR是20是普通默认优先级NI进程的nice值用来调整优先级范围-20到19NI越小进程越容易抢到CPU截图里内核线程NI是-20优先级最高VIRT进程占用的虚拟内存大小包含所有映射的内存、swap、共享库不是实际物理内存占用比如gnome-shell的VIRT是3.6GB是它的整个虚拟地址空间大小RES进程实际驻留在物理内存里的大小也就是这个进程实打实占用的物理内存比如gnome-shell的RES是167036KB ≈ 163MBSHR进程和其他进程共享的内存大小比如共享库、共享内存段比如Xorg的SHR是8844KBS进程当前状态S休眠在等待事件唤醒I空闲内核线程R运行中Z僵尸进程截图里所有进程都是S或I状态没有异常%CPU进程占用CPU的百分比截图里所有进程CPU占用都不到1%系统负载极低%MEM进程占用物理内存占总内存的比例比如gnome-shell占了8.4%的物理内存TIME进程从启动到现在累计占用的CPU总时间精确到百分之一秒比如gnome-shell已经累计跑了82小时41分钟的CPU时间COMMAND进程的启动命令名比如Xorg是图形显示服务gnome-shell是桌面环境systemd是系统1号初始化进程2.3 ps -ef作用查看进程信息可以查看进程ID与其父进程IDPID唯一区分进程的ID号。PPID父进程的ID号。父进程产生子进程的进程叫父进程。子进程父进程产生的新进程称为该父进程的子进程。2.4 pstree作用查看进程间的创建关系加上选项 -p 可以显示进程IDpstree -sp PID 查看指定进程的族谱关系2.5 kill作用给指定PID的进程发送指定的信号kill -信号编号/信号名称 PID信号可以使用命令 kill -l 来查看信号的种类及其信号编号9号SIGKILL结束指定的进程kill -9 进程PIDkillall -9 进程名19号SIGSTOP暂停指定的进程18号SIGCONT继续指定的进程2.6 fg作用将指定的进程由后台任务放到前台执行使用方法fg 进程编号fg 1jobs: 获取当前终端的后台进程任务及其编号ps: 查看终端下的前后台任务./a.out : 在后台执行任务2.7 nice作用修改进程优先级Linux 中值越小优先级越高Windows 中相反。nice -n 优先级 进程任务nice -n 10 ./a.out以指定优先级开启进程renice -n 优先级 进程PID更改运行中进程的优先级2.8 whereis作用查看指定命令的可执行程序文件在哪里whereis的搜索范围是固定的系统标准目录比如/usr/bin、/usr/src、/usr/share/man这类系统级目录默认不会扫描你当前工作目录、桌面、项目文件夹这类用户自定义的普通路径。三、进程相关函数接口3.1 forkpid_t fork(void);功能创建一个子进程空间返回值0表示在父进程中返回子进程的PID0表示当前处于子进程中-1出错并且设置errno注意子进程完全拷贝父进程的0~3G的虚拟内存空间堆区栈区文本区数据区等)拷贝内核空间中进程控制块PCB的部分内容PID号不拷贝但是又拷贝了文件描述符父进程和子进程用户空间独立数据不能共享要想共享数据需要使用进程间通信的方法3.2 getpidpid_t getpid(void);功能获取当前进程的PID号pid_t getppid(void);功能获取当前进程的父进程的PID号PPID练习1创建2个进程分别打印自己的ID号和自己父进程的ID号int main(void) { pid_t pid1; pid_t pid2; pid1 fork(); if (-1 pid1) { perror(fail to fork); } if (0 pid1) { printf(子进程1 PID:%d PPID:%d\n, getpid(), getppid()); } else if (pid1 0) { pid2 fork(); if (-1 pid2) { perror(fail to fork); return -1; } if (0 pid2) { printf(子进程2 PID:%d PPID:%d\n, getpid(), getppid()); } else if (pid2 0) { printf(父进程 PID:%d child1pid:%d child2pid:%d\n, getpid(), pid1, pid2); } } while (1) { } return 0; }3.3 wait(进程回收函数接口)pid_t wait(int *wstatus); 功能回收子进程空间 参数 wstatus 保存子进程结束状态空间的首地址 返回值 成功返回回收到的子进程的PID 失败返回-1 WIFEXITED(wstatus) 检测子进程是否正常退出 WEXITSTATUS(wstatus) 获得子进程退出时的值 WIFSIGNALED(wstatus) 检测子进程是否被信号杀死 WTERMSIG(wstatus) 获得杀死信号的编号① wait回收子进程空间避免子进程成为僵尸进程② wait具有阻塞功能能够实现多任务同步③ 进程空间回收策略对于一直处于运行状态不会结束的进程不需要回收进程在执行有结束的情况时回收3.4 waitpidpid_t waitpid(pid_t pid, int *status, int options); 功能回收指定进程的资源和wait功能相似比wait更灵活 参数 pid -1 回收取绝对值对应的进程组内的任意进程 -100.等待GID100的进程组中的任意子进程 -1 回收任意子进程组内外 0 回收和当前调用waitpid一个组的所有子进程组内 0 回收指定ID的子进程 status 子进程退出时候的状态如果不关注退出状态用NULL options 选项 0 表示回收过程会阻塞等待 WNOHANG 表示非阻塞模式回收资源。 返回值 成功 返回接收资源的子进程pid 失败 -1 设定为非阻塞且没有回收到子进程(子进程没有结束)返回0 waitpid(0,status,0) //默认阻塞 wait(status); waitpid(0,status,WNOHANG) // 非阻塞方式 注意使用waitpid以非阻塞方式回收时要搭配轮询方式实现。#include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.h #include stdio.h #include string.h #include dirent.h #include sys/wait.h #include stdlib.h int main(void) { pid_t pid; pid_t ret; int status; pid fork(); if (-1 pid) { perror(fork failed); return -1; } if (0 pid) { printf(子进程(PID:%d)开始执行\n,getpid()); sleep(10); printf(子进程即将退出\n); exit(0); } else if (0 pid) { while(1) { ret waitpid(pid, status, WNOHANG); if (0 ret) { printf(子进程还未结束我在转一圈\n); sleep(1); } else if (0 ret) { printf(回收到 %d 子进程空间\n,ret); if (WIFEXITED(status)) { printf(子进程正常结束值为 %d\n, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf(子进程被 %d 号信号杀死\n, WTERMSIG(status)); } break; } } } return 0; }四、exec函数族① exec函数族实现的原理1fork创建子进程后执行的是和父进程相同的程序但有可能执行不同的代码分支子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时该进程的用户空间代码和数据完全被新程序替换(代码区和数据区)从新程序的启动例程开始执行。调用exec并不创建新进程所以调用exec前后该进程的pid并未改变。2将当前进程的.text、.data替换为所要加载的程序的.text、.data然后让进程从新的.text第一条指令开始执行但进程ID不变。3实现原理系统实际上是完成文本区的二进制代码替换并不创建新进程②作用执行一个新的文件在一个进程中执行另外一个文件③环境变量进程在执行代码过程中临时存放信息的变量称为环境变量int setenv(const char *name, const char *value, int overwrite); 功能设置环境变量的值 参数 name:环境变量名称 value 设置的环境变量的值 overwrite: 非0 覆盖 0 不会覆盖 返回值 成功返回0 失败返回-1功能在一个进程空间中执行另外一个文件(代码) int execl(const char *path, const char *arg, .../* (char *) NULL */); 功能可以执行任意可执行文件 参数 path要执行的文件的路径和名称 arg执行该文件需要的参数 int execlp(const char *file, const char *arg, .../* (char *) NULL */); 功能执行环境变量保存的系统路径下PATH的可执行文件 参数 file需要执行的文件的名称 arg执行该文件需要的参数 int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[]*/); int execv(const char *path, char *const argv[]); 功能可以执行任意可执行文件 参数 path要执行的文件的路径和名称 argv执行该文件需要的参数存放的指针数组 int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[],char *const envp[]); l list-----参数以列表形式传递 v : vector----参数以指针数组形式传递 p path ---- 路径,exec会自动从PATH环境变量所保存的路径下去寻找 e env ---- 环境变量,执行另一段代码时更新进程的环境变量 返回值 成功会执行另一份代码 失败返回-1实现 ls -l 功能#include head.h int MySystem(const char *pcommand) { char command[256] {0}; char *parg[10] {NULL}; int cnt 0; int i 0; pid_t pid; strcpy(command, pcommand); parg[cnt] strtok(command, ); cnt; while (1) { parg[cnt] strtok(NULL, ); if (NULL parg[cnt]) { break; } cnt; } #if 0 for (i 0; i cnt; i) { printf(parg[%d] %s\n, i, parg[i]); } #endif pid fork(); if (-1 pid) { perror(fail to fork); return -1; } if (0 pid) { execvp(parg[0], parg); } wait(NULL); return 0; } int main(void) { char tmpbuff[4096] {0}; printf(system上面\n); MySystem(ls -l); printf(system下面\n); return 0; }
延伸阅读

更多相关文章

2026/11/4 0:12:37

Linux基础命令4(查找命令)

查找命令1. grep 命令是一种强大的文本搜索工具实例:ps -ef | grep sshd查找指定ssh服务进程ps -ef | grep sshd | grep -v grep查找指定服务进程,排除gerp身ps -ef | grep sshd -c查找指定进程个数2. find 命令在目录结构中搜索文件,并对搜索…

2026/11/5 2:12:35

住房证明PDF结构化抽取:坐标锚点、批量入库与原件校验

简介:这份PDF为东莞市不动产登记权利人查询结果样张,面向需要了解住房证明开具格式、核验方式及登记查询口径的读者,可用于办理购房、贷款、户籍或材料审核前的流程熟悉与字段核对。资源包共1个PDF文件,约256KB,完整呈…

2026/11/5 2:12:35

SSM+MySQL房屋租赁系统源码部署、联调与二次开发

简介:面向计算机专业毕业设计阶段的房屋租赁系统论文文档,聚焦 SSM 框架结合 MySQL 的在线租赁平台设计与实现,适合需要选题参考、论文结构模板与技术方案梳理的本科、专科毕业生及 Java Web 入门者。全文围绕房地产租赁行业背景展开&#xf…

2026/11/5 2:12:35

微信小程序驾校预约管理系统:时段冲突与权限控制设计

简介:该资源为基于微信小程序的驾校预约管理系统毕业设计配套答辩PPT,面向计算机相关专业准备毕业设计答辩的本科生,尤其适合以小程序、信息管理系统为选题的同学。内容围绕系统首页、个人中心、学员与教练管理、驾校信息与车辆管理、教练预约…

2026/11/5 2:12:35

电力系统机组组合优化实战:GA+PSO双求解器Python工程包

简介:本资源是2021年全国大学生电工杯数学建模竞赛B题的完整解题实践包,面向数学建模初学者、电气工程专业学生及备赛本科生,聚焦电力系统优化、故障建模等典型工程问题的数学抽象与程序求解。压缩包含70个文件,主体为37个MATLAB数…

2026/11/5 2:12:35

AI项目工程化落地:从训练失败到国奖答辩的全链路框架

简介:本资源为第十七届中国计算机设计大赛人工智能挑战赛国家级二等奖获奖项目完整源码包,面向高校AI方向参赛学生、算法初学者及计算机视觉实践者,聚焦多场景智能检测任务的工程化落地。压缩包共47个文件,含15个核心Python脚本&a…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑