OS进程管理
目录进程是什么进程的创建linux下进程的状态进程状态转换的本质进程优先级进程切换进程调度进程地址空间虚拟地址空间环境变量命令行参数shell指令的本质本地变量linux的命令行关于环境变量和本地变量的命令main函数的返回值进程的终止进程等待进程程序替换进程是什么进程是运行起来的程序它不仅包含程序本身还包含OS管理一个程序运行所描述出来的结构体——PCB(包含进程调度管理所需要的各种属性以及程序本身的属性)因此进程 内核数据结构程序代码和数据。在linux中PCB就是task_struct进程的创建一般来说进程都是由另一个进程创建的因为计算机上第一个进程必然至少是操作系统本身在shell命令行中所有的进程都是由shell进程创建的这些进程的父进程都是shell。下面我们使用系统接口来创建多个子进程void sub_process()//这是让子进程执行的任务 { cout我是子进程endl; } int main() { vectorpid_t mysubprocess;//保存该进程创建的所有子进程的pid for(int i 0;i10;i) { pid_t id fork();//fork函数用来创建一个子进程对于子进程他返回0对于父进程他返回子进程的pid if(id 0)sub_process(); else mysubprocess.push_back(id); } }fork做了什么创建一个新的task_struct以及新的虚拟地址空间和页表并把父进程的task_struct和虚拟地址空间和页表的内容拷贝过来一份这就是为什么子进程执行的代码和父进程是同一份而且子进程执行的位置不是从头开始[task_struct保存了当前执行的指令的位置],然后把子进程pid等个性化的属性修改了并将子进程的task_struct挂到调度队列中去这样就有两个进程在运行了。fork为什么有两个返回值fork函数的最后一条语句是“return id;”而在这之前新的子进程已经被创建出来父子进程都会执行“return id;”因此父子进程会各自返回一次。为什么对于父子进程返回的id不是相同的在 x86-64 架构Linux下系统调用的返回值存放在%raxEAX/RAX寄存器中。内核在切换回用户态之前会手动修改这两个进程的寄存器上下文对于父进程内核将子进程的 PID进程ID写入父进程的%rax寄存器。对于子进程内核将0写入子进程的%rax寄存器。之后父进程和子进程各自恢复运行读取自己%rax里的值。于是你看到的就是同一个函数fork()返回了两个完全不同的数字。linux下进程的状态R(running)运行状态即进程PCB在调度队列里。S(sleeping)休眠状态即进程在阻塞等待某一事件的发生。可被信号中断。D(disk sleeping)休眠状态的一种读写磁盘的时候变为D状态但他是不可中断的被中断的话可能造成数据丢失尤其是在银行系统中。T(stopped)进程做了非法但是不致命的操作被OS暂停。t(tracing stop)调试的时候进程被追踪在断点处停下。Z(zombie)进程任务执行完了但是PCB还不销毁维持进程退出状态也就是返回值它保存在PCB中以供父进程和OS获取执行结果。如果没有人获取执行结果就会一直处于这个状态甚至无法被KILL。而如果父进程挂掉OS会接管并回收其子进程孤儿进程。X(dead)进程真正结束了但可能不会把PCB立即销毁因为给其他新建进程使用就不用新开空间了。注磁盘的swap分区专门用于挂起正在阻塞的进程在内存不足的时候换入换出。严重内存不足甚至可以挂起运行的进程。在系统很卡的时候进程太多或者换入换出都解决不了了OS甚至会干掉进程main函数的返回值就是把子进程的执行结果返回放到子进程PCB里给父进程读取进程状态转换的本质进程状态转换在OS中本质上就是把进程PCB放到不同的队列也就是数据结构中管理起来阻塞等待的本质就是把PCB列入到设备关联的等待队列里。注同一个PCB可以处在不同的队列中因为linux中是专门用一个链接字段做链接的。只要每种队列都维护这个字段就可以进程优先级PRI的值越小进程优先级越高默认优先级是80.为什么不直接修改PR而是通过修改NI间接修改优先级因为有可能进程正在运行此时修改优先级的话就会导致优先级混乱比如为什么当前运行的进程的优先级比其他人低还能先运行。通过先修改NI等到进程重新列入到调度队列中时再计算修改PRI这样就可以避免二义性。进程切换进程切换核心就是保存上下文数据。cpu内有很多寄存器eaxebxeippcir等用于存放临时数据。有时候进程时间片到了还没执行完需要把整套寄存器的数据存起来老内核中是直接存在PCB中下一次调度的时候再恢复这些数据。这些瞬时数据也叫做上下文数据他们保存的是进程之前运行到的位置正在计算的中间值等重要数据有了这些下次进程切换回来的时候就可以接着运行。pc程序计数器,也叫eip存放下一条要执行的指令的地址指令也是二进制存储执行后pc就加上本条指令的长度从而指向下一条指令。ir存放的是当前正在执行的指令eflag有一个标志位表示计算是否溢出每次cpu执行了一条指令后就去问pc接下来执行什么指令得到结果后就把指令从pc指向的内存加载到ir根据ir中指令的长度更新pc然后开始执行ir中的指令。进程调度进程地址空间虚拟地址空间在OS中每个进程都有一个虚拟地址空间实际上就是一个结构体对象mm_struct它里面用unsigned long变量各个分区的起止位置分区情况不同的分区存放不同类型的数据进程并不是直接申请内存的而是向自己的虚拟地址空间申请空间再通过页表映射到实际内存的位置访问一个地址的时候也是通过虚拟地址页表映射访问。子进程继承父进程地址空间子进程会创建新的虚拟地址空间和页表但是会把父进程的相关内容拷贝下来因此父子进程代码共享数据共享只读。一但子进程修改数据OS会把子进程页表上该数据地址与实际地址的映射关系改变重新开辟一个数据空间把页表上的真实地址改成新空间的地址并把旧空间的数据拷贝到新空间写时拷贝。所以父子进程共享代码和数据但又是绝对独立的所以会出现同一个地址数据内容不同的情况因为我们取地址返回的是虚拟地址父子进程虚拟地址相同但是真实地址不同。为什么写时拷贝还要把原数据拷贝一份反正还要修改因为我们不一定是直接赋值还可能是x这种基于原来值的修改。关于页表虚拟地址空间如何初始化程序编译连接后是ELF格式通过这个格式OS可以获取每个分区的大小从而对虚拟地址空间的分区进行初始化并对页表的权限位和存在位初始化。申请堆空间的本质申请堆空间的本质就是扩大虚拟空间中堆空间的范围也就是申请虚拟内存而不是申请了实际内存实际内存可以延迟开辟使用的时候才开辟。为什么要有虚拟内存页表保护内存通过页表可以防止访问只读数据或者野指针访问将进程管理和内存管理解耦合让进程以统一视角看待内存进程看到的内存的分区都是同种格式虚拟地址空间的堆区堆区比较特殊当我们malloc几次之后总共申请的这些空间不是整体使用的因此堆虚拟地址空间内部又把每一次申请的堆空间的起止位置用链表管理起来以此区分。环境变量无论是linux中的命令行bash还是windows中的图形化界面都是为了方便我们对系统进行操作而启动的进程。这些进程会读取环境变量相关的配置文件将环境变量导入到他们的进程地址空间或者从更前面创建的系统进程继承环境变量这里只是大致讲述原理也就是在上面所示的位置。由于用户的所有进程都是某个进程的子进程环境变量能被系统中的几乎所有进程获取并访问下面是环境变量的某些内容PATH这个环境变量掌管指令的默认查找路径这是为什么我们使用ls等user/bin中的系统指令时不用加路径。PWD这是当前工作目录这就是为什么进程PCB的cwd属性来源创建一个文件的时候会把文件创建在默认目录下USER登录的用户是谁这就是每个进程PCB中保存的uid的来源HOME:这个环境变量是记录当前用户的家目录。当我们登录一个bash时读取环境变量然后根据当前用户名把环境变量HOME修改为自己的家目录同时把bash进程的工作路径cwd设置为家目录。这就是为什么登录后的默认目录就是家目录。SHELL告诉用户启动的是哪个路径的bash。LOGNAME是执行身份。“su -”本质上是重新登录所以USER和LOGNAME都会同步改变。“su” 是转换执行身份不改变USER只改变LOGNAME。所以区分一个用户是以USER为主。HOSTNAME主机名LANGlanguage字符编码格式OLDPWD表示上一次改变之前的pwdcd - 就是进入OLDPWD路径。如何访问环境变量子进程的调用带参数的main函数它的参数就包括了环境变量的指针如果我们的main函数是带参数的父进程就会自动给我们传环境变量int main(int argc,char* argv[],char* envp[]) { cout envp[2] endl; }C语言库定义了一个全局变量environ他指向环境变量或者调用C库中getenv()函数extern char** environ; int main(int argc,char* argv[],char* envp[]) { cout environ[0] endl; }命令行参数shell指令的本质argc代表参数个数argv存放参数内容一个个字符串envp代表环境变量。他们都会被父进程自动传入。当我们在bash命令行输入指令的时候实际上bash拿到了一串字符串然后bash以空格为分隔符把字符串打散形成表argv,argv[0]一般是可执行程序的名字剩下的是不同的字符串在bash启动argv[0]进程时把这些不同的字符串传入该进程的main函数main函数可以根据字符串的不同执行不同的功能这就是指令和指令的选项的本质。本地变量本地变量是shell在堆上创建的一张变量表供shell进程自己使用它不像环境变量一样会被子进程保留子进程不会看到它。linux的命令行关于环境变量和本地变量的命令main函数的返回值我们都知道子进程执行结束后会进入Z状态没有人回收子进程他就会一直存在在这个状态下子进程的PCB会保存main函数的返回值回收子进程的进程可以拿到这个返回值。进程的终止在main函数中return。return只会退出当前函数。exit。exit在程序的任何位置调用都会终止进程并刷新语言级缓冲区。_exit。_exit在程序的任何位置调用都会终止进程但不会刷新语言级缓冲区。exit和_exit的区别就是_exit是系统调用接口而exit是c语言提供的函数内部封装了_exit。由于C语言或c先使用的缓冲区是语言级缓冲区不是由操作系统管理那么就造成一个现象exit会刷新语言级缓冲区而_exit已经是系统调用无法操作语言级缓冲区系统无法向上管理因此_exit退出时仍在语言级缓冲区的数据将无法打印出来除非手动调用fflush函数。而遇到\n会自动刷新缓冲区这两个调用就没什么区别了。进程等待子进程必须要被父进程等待回收才能完全销毁PCB销毁。而进程的PCB会记录进程的退出码和收到的信号。进程程序替换我们创建进程只介绍了fork函数创建子进程它创建出来的子进程默认就会执行父进程的代码那么我们可以不让子进程执行父进程的代码而执行全新的一个程序吗答案就是进程程序替换我们可以对一个进程进行进程程序替换把该进程对应的代码和数据都替换成新程序的代码和数据再修改一下PCB这样他执行的就是新程序的内容了这不是创建新进程而是用老进程的壳子执行新程序。ubuntu下查询进程和网络服务的命令ps auxa显示所有终端下的进程包括其他用户的进程。u以面向用户的格式输出提供更详细的信息如CPU、内存使用率。x显示没有控制终端的进程通常是后台运行的守护进程daemon。sudo netstat -tulnp-t显示 TCP 协议的连接-u显示 UDP 协议的连接-l仅显示处于 Listening监听 状态的端口即提供服务等待连接的-n以数字形式显示 IP 和端口不做 DNS 反向解析这样显示速度极快-p显示占用该端口的进程 PID 和程序名称

相关新闻

【无标题】sqli-labs通关教程

【无标题】sqli-labs通关教程

第一关1.判断注入类型?id1 and 12 -- //不显示用户名 ?id1 and 12 -- //正常显示用户名 //所以第一关是字符型12生效则为字符型注入2.order by 判断行数?id1 order by 3 -- //正常显示 ?id1 order by 4 -- //报错 //所以user表是3列3,判断回显位置位置?…

2026/7/24 21:20:45阅读更多 →
【Python 虚拟环境 venv 创建与管理】

【Python 虚拟环境 venv 创建与管理】

文章目录Python 虚拟环境 venv 创建与管理 🐍什么是虚拟环境? 🤔创建虚拟环境 🛠️激活虚拟环境 ⚡在 Windows 上激活在 Unix/macOS 上激活管理依赖 📦安装包安装特定版本升级包卸载包生成需求文件虚拟环境工作流程示例…

2026/7/24 21:20:45阅读更多 →
融云:AI 客服越努力,用户越想找人工?

融云:AI 客服越努力,用户越想找人工?

只要跟任何一个智能客服对线过,相信你都能懂那种深深的无力感。不管面对什么情况,对面那个机械重复预制台词的智能客服轻轻松松就能毁掉我们的耐心。关键是,你已经忍无可忍了,它依然死板地绕着圈子且始终情绪稳定。这就是大部分智…

2026/7/24 21:18:44阅读更多 →
每天60s读懂世界:2026年7月24日15条重点新闻深度解读

每天60s读懂世界:2026年7月24日15条重点新闻深度解读

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

2026/7/24 22:36:57阅读更多 →
深度探索Beyond Compare 5密钥生成:从逆向工程到实战激活指南

深度探索Beyond Compare 5密钥生成:从逆向工程到实战激活指南

深度探索Beyond Compare 5密钥生成:从逆向工程到实战激活指南 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 还在为Beyond Compare 5的30天评估期限制而烦恼?这款被誉为…

2026/7/24 22:36:57阅读更多 →
start9 霍尔双相编码器

start9 霍尔双相编码器

一、编码器1.什么是编码器1.增量式编码器-“记步器”核心:只记录“相对变化量”(走了多少步)特点:断电后位置丢失,上电需回零。输出连续的脉冲串。2.绝对式编码器-“坐标尺”核心:直…

2026/7/24 22:36:57阅读更多 →
tech-summary.skill

tech-summary.skill

name: tech-summary description: | 对编程语言、框架、工具等做深度技术总结,输出结构化 Markdown 知识文档。 当用户请求"总结/梳理/整理"某技术知识点、准备技术面试、系统化学习某主题时使用; 简单问答、代码调试、单点概念解释不使用本技能。 disable-model-inv…

2026/7/24 22:36:57阅读更多 →
为什么 Hermes 上手容易,团队协作时却成了“Bug 制造机”?

为什么 Hermes 上手容易,团队协作时却成了“Bug 制造机”?

聊《Hermes真能提效吗?先看流程里最慢的那一步》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要前两周,我带着团队里的几个初级开发试水了 Hermes。Demo 阶段确实惊艳:输入自…

2026/7/24 22:36:57阅读更多 →
技术解析:培训考试系统补考功能的架构设计与实操指南

技术解析:培训考试系统补考功能的架构设计与实操指南

对于企业 IT 运维人员、培训系统管理员而言,选择一款具备补考功能的培训考试系统,不仅要关注 “功能是否能用”,更要评估 “技术是否可靠”“集成是否便捷”“运维是否省心”。宏远培训考试系统的补考功能,基于微服务架构设计&…

2026/7/24 22:34:57阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/24 19:00:40阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/24 19:00:40阅读更多 →