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

【Linux】进程 PCB、task_struct、fork初识

  1. 在Linux系统里面PCB是一个结构体,也就是接下来所要讲的task_struct这个结构体。所有运行中的进程都以task_struct双链表的形式存在于内核里。
  • PCB != task_struct,task_struct只是PCB的一种

二. task_struct

1. 内容属性
1.1 标识符
  1. 每一个进程都会被分配一个唯一的标识符id,用来区分不同的进程。我们用命令getpid来获取一个进程的pid。
  2. 在一个进程里可以创建另一个进程,这个被创建的进程叫做子进程,而创建它的进程叫做父进程。task_struct里面还会存储一个进程的父进程的id。我们用命令getppid来获取一个进程的父进程。
1.2 状态 + 优先级 + 程序计数器 + 内存指针 + I/O状态信息 + 记账信息
  1. 状态信息:代表程序是否正在运行,暂停或退出。一般会用一个整型值来表示这几个状态。
  2. 优先级信息:相对于其他进程当前进程的优先级。它决定了进程被调度执行的顺序和频率。
  3. 程序计数器:它存储的是程序即将执行的下一条代码的地址。它能够保证进程能够恢复执行的位置。
  4. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  5. I/O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使用的文件列表。
  6. 记账信息:可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
1.3 上下文数据
  1. 在进程运行时对应的PCB里面的数据不是实时更新的,像上下文数据只会在上下文切换时才会保存。
  2. cpu里面是有一套寄存器的,这些寄存器会存储当前进程的运行状态,这个是会随着进程的运行实时更新的。
  3. cpu只有一个,也只有一套寄存器,这意味着单个cpu无法同时处理多个进程
  4. 一个进程执行代码,占用cpu,难道要等这个进程的代码执行完才会让出cpu吗?这显然不是的。现代计算机里都会有一个时间片,运行了一定的时间之后就会自动退出,把cpu让出来。这代表进程可能没有执行完就已经把cpu让了出来,因为时间片一到达,就会有进程切换和调度。之后这个寄存器里存储的这个进程的运行状态的所有数据就会被它的PCB里的上下文数据带走。
  5. 为什么一定要带走这份数据呢?因为这个程序是很有可能没有执行完的,如果我下一次又来执行这个进行的代码,难道我要从头开始执行这个程序吗?显然不是的,因为上下文数据把最后运行时的寄存器里面的数据带走了,可以接着运行这个进程。
  6. 比如上下文数据就会带走寄存器里面存储程序计数器的值,这样就知道程序代码执行到哪里了。
  • 上下文数据包含很多内容比如程序计数器,它在进程切换时会带走cpu寄存器里面所有的数据。然后进程恢复时再将这些数据还给寄存器。
2. 查看进程
/proc
  1. 进程的信息可以通过/proc系统文件夹进行查看。下面那些前半部分的数字(PID)还有self对应的就是一个个的进程目录,这些目录里面存储的是进程的属性。

在这里插入图片描述

  1. 比如查看目录1的内容,里面就是对应进程的属性:

在这里插入图片描述

ps
  1. 进程信息也可以通过ps和top这些用户级工具来进行获取。
  2. 这里我们创建一个test.c文件如下(忘加<unistd.h>头文件了,最好加上),编译后运行。

在这里插入图片描述

  1. 我们用指令ps axj | head -1 && ps axj | grep test来查看进程。其中ps axj是用来查看所有进程的,第一行会有列标,所以用head -1来将第一行显示出来,grep test能够筛选出所有进程里面包含test的进程。
  2. 从下面的图片可以看到,用ps axj是能够直接看到PPID、PID等属性的。
  3. 其中除了用’ ; '来分隔指令之外还可以用&&来进行分割。

在这里插入图片描述

  1. 我们用ls -l查看进程test的具体属性:这里test的PID跟下面的不一样,因为PID是随机分配的,而不是固定的。

在这里插入图片描述

  1. 这里我们要着重关注一个叫做cwd的符号链接文件,它里面指向的是当前进程的工作路径。当进程打开一个不存在的文件时(比如fopen),这个文件会被创建,且默认会创建在这个当前运行进程的工作路径下面。如果我们修改这个pwd所指向的工作路径,那么新创建的文件也会在新的工作路径下面。
3. getpid、getppid
  1. 之前了解到getpid能够用来获取进程的PID,而getppid可以用来获取一个进程的父进程PID也就是PPID。
  2. 在Linux系统中,一个新的进程往往是通过父进程产生的。

在这里插入图片描述

3.我们可以看到test.c的父进程PID也就是PPID是17348,那这个17348究竟是哪个进程?我们来看看。

在这里插入图片描述

  1. PID为17348的是一个叫做bash的进程。bash是目前最主流的命令行解释器。它本质是终端的子进程,负责执行我们输入的命令。也就是运行test这个文件。test也就称为了它的子进程。

在这里插入图片描述

  1. 使用getpid和getppid:需要包含头文件<sys/types.h>:定义了pid_t等系统类型(用于表示进程 ID)和<unistd.h>:提供系统调用的函数声明(Unix 标准头文件)。它会返回一个pid_t类型的pid或ppid。pid_t类型底层是用整型实现的。但是具体是int还是long这取决于系统架构。

在这里插入图片描述

三、 初识fork

在这里插入图片描述

  1. fork是用来创建子进程的函数。

在这里插入图片描述

  1. fork有两个返回值,一个会返回给父进程,一个会返回给这个新创建的子进程。如果进程创建成功,返回给父进程的会是这个子进程的PID,返回给子进程的会是0,代表创建成功;如果创建失败,返回父进程的是-1,子进程不会创建。
  2. 子进程父进程的代码是共享的,本质也就是在子进程创建时,它的task_struct也会指向父进程的代码和数据(这份代码是只读的,也就意味着共享无风险。这就代表着fork(如果子进程创建成功)之后的代码会执行多次。

在这里插入图片描述

在这里插入图片描述

  1. 可以看到,有两个不一样的PID,说明有两个进程执行了同一行代码,而且其中一个还是另一个进程的父进程(15681的父进程是15680)。
  2. 如果我们不想让子父进程执行相同的代码,我们就可以利用fork的返回值来进行分流进而达到目的:如果创建成功,返回给子进程的是0,而返回给父进程的是一个大于0的数。

在这里插入图片描述

  1. 为什么创建成功给父进程返回的是子进程的pid,而给子进程返回的是0?这是因为一个进程的父进程只能有一个,但是子进程可以有多个,它们之间是1:n的关系。如果我身为一个父亲,我肯定要给孩子取不同的名字,不然就认不清了。子进程不需要通过返回值找父进程,而父进程需要通过返回值找子进程,因为父进程能有多个子进程。
  2. fork()是一个函数,可是为什么却返回了两次?这是因为fork函数的实现里面在return之前就已经完成了子进程的创建,那么return自然就会有两次执行,return的本质其实也就是写入操作

今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~让我们共同努力, 一起走下去!


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

相关文章:

  • 基于二进制的遗传算法的考虑排放目标和输电损耗的经济调度研究(Python代码实现)
  • 扫地机机器人研发岗深度解析与技术指南
  • 140个企业级实战场景剖析以及AI大模型项目实战
  • 函数式编程思想
  • 2026钻床市场热门:这些工厂钻床受追捧,目前优质的钻床品牌技术引领与行业解决方案解析 - 品牌推荐师
  • 汇源全屋定制作为全屋定制专业制造商,价格大概多少钱? - 工业推荐榜
  • 基于改进粒子群算法的含碳捕集微网多时间尺度低碳经济调度(Matlab代码实现)
  • Flutter 三方库 system_resources_2 的鸿蒙化适配指南 - 实时监控鸿蒙端侧 CPU 负载、内存占用与系统资源动态感知
  • 星焰家居这个不锈钢全屋定制厂商品牌靠不靠谱,值得推荐吗? - myqiye
  • 2026年热门的CNC 精密压铸加工公司推荐:医疗设备精密压铸加工/智能家居精密压铸加工采购指南厂家怎么选 - 行业平台推荐
  • # 发散创新:WebHID 在浏览器端实现外设通信的全新实践 在现代Web 开
  • 2026年评价高的储能弹簧工厂推荐:耐腐蚀弹簧/小家电电磁阀弹簧/高压直流继电器弹簧精选厂家推荐 - 行业平台推荐
  • Python开发英语记忆单词软件 - 优化
  • FFMpeg + WebSocket + JSMpeg 搭建低延迟视频系统(总览篇)
  • 2026年01月深圳CE:加速寿命试验/合规类/国内外认证/机构类/测试服务/温度老化试验/电子电气检测/腐蚀试验/选择指南 - 优质品牌商家
  • 2026国内小白纹绣培训重实操机构推荐榜:野生眉学校、零基础学纹眉、零基础小白、零基础纹眉学校、零结痂雾眉、韩式定妆学校选择指南 - 优质品牌商家
  • PAT 乙级 1078
  • 谁懂啊!OpenClaw(小龙虾)爆火不是没道理
  • Python基于flask的博客系统设计与实现
  • 总结AI蓝牙音箱生产厂,国内靠谱厂家Top10有哪些? - 工业品网
  • Flutter 三方库 shelf_cors_headers 的鸿蒙化适配指南 - 实现具备跨域安全访问策略的服务端拦截器、支持端侧微服务网关与分布式请求治理实战
  • 聊聊扬州月子中心按需定制,哪家品牌靠谱又有高性价比? - 工业设备
  • win11下解决eNSP AR启动40/41错误解决方案
  • Flutter 三方库 health_connector_core 的鸿蒙化适配指南 - 实现具备跨平台标准的数据采集与同步架构、支持端侧健康指标建模与设备总线协同实战
  • 牛客练习001:反转链表
  • 基于Matlab 2017a的单相交交变频电路仿真研究:阻感负载下的傅立叶分析与原理讲解
  • python flask django教师教学计划系统 计算机科学拔尖学生培养基地
  • Python基于flask的图书借阅系统的设计与实现_
  • 30 分钟搭出你自己的 OpenClaw:保姆级安装教程(2026版)
  • python flask django考研学习资料商城信息服务平台