Linux系统 —— 进程系列 - 进程的概念,PCB与PID和fork

目录

1. 进程的基本概念与基本操作

1.1 总结:什么才是进程

2. 描述进程-PCB(process control block)

2.1  task_ struct

2.2 task_ struct内容分类

2.3 组织进程

3. PID 

获取当前进程PID - getpid

获取父进程PID - getppid

如何查看进程

1 进程的信息可以通过 /proc 系统⽂件夹查看

2 我们还可以使⽤top和ps这些⼯具来获取

4. fork - 创建子进程

4.1 为什么fork要给父进程返回子进程的pid, 给子进程返回0呢?

4.2 fork函数为什么会返回两次?

总结:


1. 进程的基本概念与基本操作

课本概念:程序的⼀个执⾏实例,正在执⾏的程序等

   
内核观点:担当分配系统资源(CPU时间,内存)的实体

但是,上面的内容对于我们初学者来说是非常难以理解的,所以我们可以画图来进行理解 

一个程序运行起来叫做进程,未运行起来就是一个二进制文件,存储在磁盘当中,程序运行之前要加载到内存,在操作上就是(./cmd) ,而真正意义当我们执行时cmd就会加载到内存当中去

  

 
这里我们是把一个程序加载到内存,有没有可能我们在操作系统里,在同一时刻我们可以把成百上千给程序加载到内存里呢?答案是一定的

  

而有一款软件是最开始就加载进来了,叫做操作系统

  

  

如上图,我们可以看到在内存中,有很多加载的程序,那么我们就有一个问题:这些程序在内存中的什么位置被加载?代码和数据是否已经被cpu已经执行完毕呢?有没有可能其中的程序需要暂停运行?有没有可能其中内存不够了,需要扩容呢?

  

所以在内存中有这么多加载的内存,它们都需要申请内存和加载内存,所以操作系统要对这些进程,这些代码进行管理,但是我们可以做管理吗?答案是不能,因为操作系统虽然知道里面有代码,但是操作系统并不知道是那个进程

  

但是我们有没有解决方法呢?答案是先描述,再组织

  

     

  

操作系统会在操作系统内部(内核)给每一个代码和数据构建一个struct结构体,然后每加载进来一个程序,操作系统就为该程序创建一个同类型的对象,然后把当前这个进程按照创造的对象填写好信息,填好之后就有了一个对应的节点,而这里每一个节点都有对应的指针可以指向对应的代码和数据

  

与此同时,我们对应的每个节点当中,它的指针还可以指向它的下一个节点,最终在操作系统内我们形成了一个程序列表,我们把这个程序列表叫做进程列表

  

1.1 总结:什么才是进程

  ​​​​​​


2. 描述进程-PCB(process control block)

其实我们上面已经见过PCB了,就是我们上面创建的结构体,在操作系统中所有表示进程的都叫PCB,而这个结构体叫做进程控制块

  

  

进程控制块里包含进程的所有属性,进程的所有属性都可以直接或者间接通过 task_ struct找到

    

进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合

  

所以为什么一个进程加载的时候操作系统要给它创建一个对应的PCB即task_ struct对象呢?

      

因为操作系统要管理进程,所以要先描述,再组织,所以必须要有描述进程的task_ struct再组织管理成数据结构,操作系统就会转化成对应数据结构的增删查改

  

操作系统要对进程做管理,那么就必须要对进程的PCB做管理


2.1  task_ struct

Linux中进程控制块PCB-------task_struct结构体结构 - 童嫣 - 博客园icon-default.png?t=O83Ahttps://www.cnblogs.com/tongyan2/p/5544887.html

1. 在Linux中描述进程的结构体叫做task_struct

   

2. task_struct是Linux内核的⼀种数据结构,它会被装载到RAM(内存)⾥并且包含着进程的信息


2.2 task_ struct内容分类

   
1. 标示符: 描述本进程的唯⼀标⽰符,用来和其他进程进行区别

    
2. 状态: 任务状态,退出代码,退出信号等

    
3. 优先级: 相对于其他进程的优先级

   
4. 程序计数器: 程序中即将被执⾏的下⼀条指令的地址

   
5. 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针

    
6. 上下文数据: 进程执⾏时处理器的寄存器中的数据[休学例⼦,要加图CPU,寄存器]

    
7. I/O状态信息: 包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表

    
8. 记账信息: 可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等

    
9. 其他信息


2.3 组织进程

所有运⾏在系统⾥的进程都以task_struct链表的形式存在内核里

  

在linux内核中, 最基本的组织进程task_struct的方式, 是采用双向链表进行组织的


3. PID 

获取当前进程PID - getpid

   

进程创建的时候, 里面都有一个自己的PID,我们如何在一个程序运行时获取这个程序的PID呢?

如图所示,操作系统里面上层是系统调用, 下层是内存缓冲区, 这个时候内存中已经缓存了两个进程,PCB对象里面含有PID,我们可以使用ps axj和管道来获取进程的PID

  

但是我们都知道,操作系统不相信我们用户, 所以我们就不能直接访问PCB(task_struct)也就是里面的PID, 状态等, 想要获取这些字段就必须使用系统调用接口

  

如果我们想要获取当前进程的PID的系统调用接口的话,我们就要使用getpid(), 这个函数在哪个进程里被调用, 就会返回哪个进程的PID

   

注意:pid是一个整形, 下面是我们自己定义的一个获取系统调用接口的程序

当前进程为: 


获取父进程PID - getppid

对上面的概念进行试验之后, 我们再来看一下父进程, 也就是PPID 

我们发现,父进程ppid都是不改变的,而pid每次都是变化的,这是为什么呢?

  

我们联想到王婆的例子

  

  

王婆不想给自己的牌子砸了,所以就找了些实习生去解决,不需要王婆亲自去解决了,派实习生去解决,所以我们的-bash就是王婆(父进程)

  

1.运行一个进程时,系统会自动创建bash进程

   
2.命令行再执行所有的程序或者指令时,它所对应的进程,所对应的父进程就是bash本身。我们自己执行的程序或者指令都是bash进程的子进程

   
3.执行出问题的时候,只会是子进程出问题,不会影响bash进程

   
4.我们启动xshell时候,系统自动生成bash进程,显示命令行

如何查看进程

1 进程的信息可以通过 /proc 系统⽂件夹查看

   
如:要获取PID为1的进程信息,你需要查看 /proc/1 这个⽂件夹

proc文件夹里面的目录都是临时文件,当进程开始就会创建一个以这个进程的pid作为名字的文件夹,进程结束的时候就会删除这个文件夹  

我们发现: 这些进程都是目录, 并且这些目录的名字都是数字 

我们可以通过proc文件来查看这个进程更详细的信息

 


2 我们还可以使⽤top和ps这些⼯具来获取

 ps:

top:

在命令行中,执行命令/执行程序,本质是bash的进程,创建子进程,来执行我们的代码


4. fork - 创建子进程

fork是一个系统调用,fork没有参数,有两个返回值

   
父子进程代码共享,数据各⾃开辟空间,私有⼀份(采用写时拷贝)

  

fork函数的本质就是是一个系统调用

上面那张图意思就是说如果fork函数成功了, 那么给父进程返回子进程的pid, 0返回给子进程。 如果失败了, 就返回 -1 给父进程。 并且没有子进程被创建

   

也就是说, fork有两个返回值, 并且这两个返回值的类型都是pid_t, 也就是有符号整形

 运行结果:

我们可以看到每一秒打印一条父进程, 打印一条子进程,这说明父进程和子进程是同时进行的,并且id > 0,   和 id == 0同时成立, 如果在其他的代码中, 这两种情况不可能同时存在,但是在调用的fork下就可以

  

所以在我们fork之后所有的代码都是共享的,只不过父进程认为自己>0,子进程认为自己=0,所以父进程会进入第三个,子进程会进入第二个,所以我们就可以做到父子执行不同的代码块

  


到了这里,我们有几个问题


4.1 为什么fork要给父进程返回子进程的pid, 给子进程返回0呢?

在我们的操作系统里,我们的父进程比上子进程是1:N的,简单来说就是任何一个父进程可以有一个或者多个子进程

   

所以我们在创建子进程时,一定要把子进程的pid返回给父进程,因为父进程需要通过返回的不同的pid来区分不同的子进程,而子进程不需要获得父进程的pid,因为子进程已经能够获得getppid了,所以子进程只需要表明自己成功建立就可以了

  


4.2 fork函数为什么会返回两次?

在这个问题之前我们先讨论另一个问题:一个函数执行到return时,函数的核心功能做完了吗?答案是核心功能已经完成了

  

fork函数的本质就是是一个系统调用

 

如图所示:fork函数创建子进程后, 函数后面的代码就会被子进程和父进程所共享

    

当fork函数里面创建好子进程后(绿色方框部分) 子进程就被创建出来了, 然后执行流就变成了两个(可以使用if或者else或者else if来进行分流), 一个子进程的执行流, 一个父进程的执行流

   

也就是说, 这个时候的return语句, 其实就是由两个执行流会执行它,因为return也是语句,所以会被执行两次,而这两个执行流都会返回一个值,所以这就是为什么fork会有两个返回值, 并且返回值给一个给子进程, 一个给父进程的原因


总结:

  

1. 进程具有独立性,简单来说就是一个进程挂掉了并不会影响其他进程,哪怕是父进程挂掉了也不会影响子进程

  

如果子进程和父进程公用一个数据块, 当子进程改变数据的时候, 父进程也会改变数据,所以 不能让父进程和子进程共享一份数据

   

对于子进程来说数据是独立的,所以当创建子进程的时候要拷贝一份父进程的数据独立出来

  

这个时候父进程崩溃或者子进程崩溃都不会影响对方

 


未完待续~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/486453.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模型训练数据-MinerU一款Pdf转Markdown软件

模型训练数据-MinerU一款Pdf转Markdown软件-说明 简介: MinerU是什么 MinerU是上海人工智能实验室OpenDataLab团队推出的开源智能数据提取工具,专注于复杂PDF文档的高效解析与提取。MinerU能将包含图片、公式、表格等元素的多模态PDF文档转化为易于分析…

第32天:安全开发-JavaEE应用Servlet路由技术JDBCMybatis数据库生命周期

时间轴: 32天主要学习内容: 1、JavaEE-HTTP-Servlet技术 2、JavaEE-数据库-JDBC&Mybatis java技术使用历史(2023 ): JavaEE-HTTP-Servlet&路由&周期: java学习范围: 3、Java: 功能:数据…

LSTM-CNN-BP-RF-SVM五模型咖喱融合策略混合预测模型

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 LSTM-CNN-BP-RF-SVM五模型咖喱融合策略混合预测模型 Matlab代码注释清晰。 程序设计 完整程序和数据获取方式:私信博主回复LSTM-CNN-BP-RF-SVM五模型咖喱融合策略混合预测模型(Matlab&#…

D91【python 接口自动化学习】- pytest基础用法

day91 pytest的setup,setdown详解(三) 学习日期:20241207 学习目标:pytest基础用法 -- pytest的setup,setdown详解(三) 学习笔记: setup、teardown详解(三…

Spring事务的一道面试题

每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。 原理 Spring事务的原理是:通过AOP切面的方式实现的,也就是通过代理模式去实现事务增强。 具体过程是&a…

【无标题】建议用坚果云直接同步zotero,其他方法已经过时,容易出现bug

created: 2024-12-06T16:07:45 (UTC 08:00) tags: [] source: https://zotero-chinese.com/user-guide/sync author: 数据与文件的同步 | Zotero 中文社区 Excerpt Zotero 中文社区,Zotero 中文维护小组,Zotero 插件,Zotero 中文 CSL 样式 数…

室联人形机器人:家政服务任务结构化、技术要点、深入应用FPGA的控制系统框架设计(整合版)

目录: 0 引言 1 人形机器人对室内家政服务任务的结构化 1.1人形机器人在室内家政服务中的比较优势 1.1.1 人形机器人拟人性的7个维度 1.1.2 拟人性在室内家政服务工作中的比较优势 1.1.3 潜在的重要用户:宠物爱好者 1.2 居所室内环境的特征与结构…

基于stm23的智慧宿舍系统 (DAY10)_小程序

好久没记录开发进度了,今天小程序差不多开发完了,UI这块算是比较常见了,主要功能是能连接onenet查看设备上传的数据,同时也能对设备进行一些控制下面是几个主要的函数,功能比较简单 wx.request({url: ${apiBaseUrl}/t…

ruoyi-nbcio为安全起见actuator为仅暴露health端点

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…

Vant UI +Golang(gin) 上传文件

前端基本用法:点击查看 实现代码: const afterRead (file) > {console.log(file);//set content-type to multipart/form-dataconst formData new FormData();formData.append("file", file.file);request.POST("/api/v1/users/up…

鸿蒙分享(一):添加模块,修改app名称图标

码仓库:https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 新建公共模块common 在entry的oh-package.json5添加dependencies,引入common模块 "dependencies": {"common": "file:../common" } 修改app名称&…

图像处理网络中的模型水印

论文信息:Jie Zhang、Han Fang、Weiming Zhang、Wenbo Zhou、Hao Cui、Hao Cui、Nenghai Yu:Model Watermarking for Image Processing Networks 本文首次提出了图像处理网络中深度水印问题,将知识产权问题引入图像处理模型 提出了第一个深…

C# Decimal

文章目录 前言1. Decimal 的基本特性2. 基本用法示例3. 特殊值与转换4. 数学运算示例5. 精度处理示例6. 比较操作示例7. 货币计算示例8. Decimal 的保留小数位数9. 处理 Decimal 的溢出和下溢10. 避免浮点数计算误差总结 前言 decimal 是 C# 中一种用于表示高精度十进制数的关键…

网络安全协议基本问题

Http和Https协议的端口号: Http:80 Https:443 网络监听: 网络监听是一种监视网络状态、数据流程以及网络上信息传输的工具,它可以将网络界面设定成监听模式,并且可以截获网络上所传输的信息。但是网络监…

贪心算法part05

文章参考来源代码随想录 (programmercarl.com) 56. 合并区间 本题和前几题类似,都是判断上一个元素的右边界与当前元素的左边界大小关系 但是需要注意是:本题需要更新结果数组元素的右边界,因此比较的是数组最后一个元素右边界与当前元素左…

【Spring篇】初始Spring MVC框架之Spring MVC入门程序编写

🧸安清h:个人主页 🎥个人专栏:【计算机网络】【Mybatis篇】【Spring篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎯Spring MVC概述 …

深度学习图像增强介绍

目录 一、引言二、常用数据增广方法三、图像变换类3.1 AutoAugment3.2 RandAugment 四、图像裁剪类4.1 Cutout4.2 RandomErasing4.3 HideAndSeek 五、图像混叠5.1 Mixup5.2 Cutmix 六、结论 一、引言 在图像分类任务中,图像数据的增广是一种常用的正则化方法&#…

Python办公—DataMatrix二维条码制作

目录 专栏导读1、库的介绍2、库的安装3、核心代码4、完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…

SAP导出表结构并保存到Excel 源码程序

SAP导出表结构并保存到Excel,方便写代码时复制粘贴 经常做接口,需要copy表结构,找到了这样一个程程,特别有用。 01. 先看结果

基于Java Springboot在线招聘APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 微信…