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

【Linux】从零开始认识进程 — 前篇

在这里插入图片描述
我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。。——山本耀司

从零开始认识进程

  • 1 认识冯诺依曼体系
  • 2 操作系统
  • 3 进程
    • 3.1 什么是进程???
    • 3.2 进程管理
      • PCB
    • 3.3 Linux中的进程
      • 深入理解
    • 3.4 进程创建
    • 总结
  • 送给大家一句话:
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

1 认识冯诺依曼体系

学习进程,我们需要对计算机操作系统 有一个初步的了解,也就是经典的冯诺依曼体系:
计算机的逻辑结构。冯·诺依曼从逻辑入手,他的逻辑设计具有以下特点:
(1)将电路、逻辑两种设计进行分离,给计算机建立创造最佳条件;
(2)将个人神经系统、计算机结合在一起,提出全新理念,即生物计算机。
符合人们的一般认知:
在这里插入图片描述
我们所认识的计算机,都是有一个个的硬件组件组成

  1. 输入单元:包括键盘, 鼠标,扫描仪, 写板等
  2. 中央处理器(CPU):含有运算器和控制器等
  3. 输出单元:显示器,打印机等

关于冯诺依曼体系结构,必须强调几点:

  1. 这里的存储器指的是内存
  2. 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)外设(输入或输出设备)
  3. 要输入或者输出数据,也只能写入内存或者从内存中读取。
  4. 一句话,所有设备都只能直接和内存打交道。

对冯诺依曼的理解,不能停留在概念上,要深入到对软件数据流理解上

了解冯诺依曼体系结构,接下来我们来认识操作系统

2 操作系统

操作系统可以理解为硬件和用户层面之间的一个软件。让用户通过操作系统可以来对硬件进行访问。那为什么不让用户直接操作硬件呢?打个比方:
我们把银行抽象为一台电脑,银行的金库是我们的硬盘,而我们想要去银行取钱或存钱(获取数据/存入数据),那你说如果我们每个人都可以进入到金库自行行动,(相信大家都是有道德感的人,会如实操作),但群众中里肯定有坏人,假如他存1000元,却报告存了10000元,那银行系统就要崩溃了。所以才会有银行柜台(相当于操作系统提供的接口)让我们可以正常进行操作,不会发生恶性事件

操作系统是必然存在的在整个计算机软硬件架构中,操作系统的定位是: 一款纯正的“搞管理”的软件
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
内核(进程管理,内存管理,文件管理,驱动管理)其他程序(例如函数库, shell程序等等

设计OS的目的:

  1. 与硬件交互,管理所有的软硬件资源
  2. 为用户程序(应用程序)提供一个良好的执行环境

这里通过一个图示,供大家学习使用:

在这里插入图片描述
系统调用和库函数概念:

  1. 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  2. 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库(lib),有了库,就很有利于更上层用户或者开发者进行二次开发。

这里也可以解释为什么有些代码不具有跨平台性了:
因为直接访问的操作系统的调用接口与平台紧密相关。平台不同(操作系统不同)那系统调用接口,返回值等大概率不同,所以不具有跨平台性
c/c++ 具有跨平台性

接下来我们来学习进程!

3 进程

3.1 什么是进程???

相信大家一定对这个词充满陌生(不管你陌不陌生,反正我第一眼看是不理解什么是进程,太抽象了),但实际上,我们每天都在接触进程(除非你不玩手机,不用电脑)。那我们就俩看看电脑的进程是怎样的吧:
非常简单,我们打开任任务管理器,看见的都是正在进行的进程
在这里插入图片描述
这都是正在进行的进程,所以进程并不高深,是十分常见。
基本概念:

  1. 课本概念:程序的一个执行实例,正在执行的程序等
  2. 内核观点:担当分配系统资源(CPU时间,内存)的实体

我们也同任务管理器看到,进程是可以同时存在非常多的

3.2 进程管理

我们知道了进程是什么,那接下来我们来聊聊进程是如何进行管理的吧

进程是通过PCB来进行描述和管理的
进程 = PCB + 自己的数据和代码

PCB

PCB 实质上是一种结构体,里面包含该进程的信息,和下一进程的地址:类似如下结构

struct PCB{//所有属性//指向下一个进程struct PCB* next;//内存指针//储存对应数据,代码等//....
}

一个进程一定要有一个PCB。

那为什么要有PCB呢???:因为操作系统(os)要对进程进行管理!!!

3.3 Linux中的进程

每个操作系统都有自己对应的PCB模块,那我们来看一下linux 的PCB是什么样子:

struct task_struct{//Liunx 进程控制模块  
}

在linux里,通过链表进行的PCB管理 ,同时使用队列里选择任务进行运算。即:

  1. 在队列里取出任务
  2. 找到任务对应的PCB
  3. 通过PCB调用对应数据进行CPU运算。

调度运行进程,本质就是让进程控制块task_struct进行排队!!!

在根据进程的概念我们可以理解linux的进程为:
进程 = 内核task_ struct结构体 + 程序的代码和数据

深入理解

现在我们来进入到linux中来看看进程的Task_struct本身内部的属性都有哪些???
现在,linux 启动!!!
在这里插入图片描述
. / 的本质就是让系统创建进程并运行 (此外每个指令也是一个可执行程序)
我们自己写的代码形成的可执行程序 == 系统命令 == 可执行程序。
在Linux 中大部分的执行操作本质都是运行进程!!!

现在我们再来看看Linux中的“任务管理器”,让我们一起来看看然后才能查看进程
ps ajx 可以查看我们的进程,为了方便演示我们使用grep 来进行一下筛选:
ps ajx | grep myprogress
在这里插入图片描述在下面的 grep -…也是我们的进程,因为每次grep查找 都会形成进程 因而就会出现两个进程。
接下来我们来认识一下具体属性:
我们使用ps ajx | head -1(即只打印第一行)
在这里插入图片描述
然后怎么查看对应信息呢???光看到这一行也无法理解
使用指令 && 指令 即可:
在这里插入图片描述
这样我们成功打印出来进程信息,我们来认识一下:

  1. PID : 每一个进程都要有自己的唯一标识符,叫做进程PID

那么我们能不能通过可执行程序自己查到我们的PID呢?(这样就省去ps命令了)。
当然可以!!!
pid 储存在 struct task_struct 中,而struct task_struct 是内核数据结构,用户不能轻易访问(上面有讲到为什么不能访问),那么如何才能获取呢???当然是使用系统提供给我们的接口了
pid_t getpid() 就是这样的接口。我们把接口加入到我们的代码中试试。
(getppid () 是返回父进程 )
在这里插入图片描述
我们验证一下,PID是否正确:
在这里插入图片描述
显然 pid 的打印是正确的!!!

我们可以成功进行进程了,那么有没有方法可以结束进程呢???
当然有了!
kill -9 pid 就可以干掉想要结束的进程了,(kill是不是非常霸气!!!,起码把微软的结束进程霸气多了)
我们来尝试一下:可以看到我们成功kill 掉了正在进行的进程!
在这里插入图片描述
记住:

  1. Ctrl + C 就是在用户层面终止进程,kill -9 pid 可以用来直接杀掉进程!!!

3.4 进程创建

首先来解释一下父进程,ppid 是父进程的ID
pid_t getppid()返回父进程的ID,而子进程是由父进程创建的,这里只做了解。
下面演示一下如何获取父进程的ID:
在这里插入图片描述
这样我们就获取到了父进程ID。
当我们多次运行时,每次进程PID都是不同的,但是父进程ID是相同的(每次运行 PID 不同是正常的)

那我们追溯一下这个父进程到底是谁
同样使用grep差找到该进程
在这里插入图片描述
可以看到的 父进程是bash,什么是bash???可以先理解为命令行解释器。目前还没有深入探讨的能力

接下来我们来尝试是否可以手动实现创建子进程
首先来认识一下 fork函数
fork() (可以通过运行 man fork 认识fork)

  • fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
  • 创建一个进程,本质是系统中多一个进程,多一个进程,就是多一个内核task_struct
  • 父进程的代码和数据是从磁盘加载来的,子进程的代码和数据会默认进程父进程的代码和数据

为什么要创建子进程呢:因为我们想要通过子进程与父进程执行不一样的代码,在特殊情况下可以提高运行效率。

接下来我们来认识一下fork()函数的返回值,因为他两个返回值(与以往的认识函数不一样)。

  1 #include<stdio.h>  2 #include<unistd.h>  3 #include<sys/types.h>  4   5 int main(){  6   7   printf("process is running ,only me! pid: %d \n",getpid() );  8   fork();  9   pid_t id = fork();  10   11   if(id == -1) return 1;  12   else if(id == 0){  13     //child  14     while(1)  15     {   16       printf("id : %d I am child process,pid: %d, ppid: %d\n",id,getpid(),getppid());         17       sleep(1);                    18                                    19     }                              20   }                                21   else{                            22     //parent                       23     while(1){                                               25       printf("id : %d I am parent process,pid: %d, ppid: %d\n",id,getpid(),getppid());  26       sleep(2);                    27     }                              28                                    29   }                                30                                                 31   } 

简单写一下测试程序,来看效果:
可以看出是成功运行出子进程和父进程
在这里插入图片描述
刚才的代码,在9 行 fork()之后,子进程和父进程是共享的,因为我们进行了判断,所以子进程与父进程会执行不一样的代码,在之前学习的语法中,if 与 else 的代码不可能一起运行,这是因为之前学习的都是单进程,在多进程中可以做到,即使这样,那也也有很多疑问:

  1. 同一个 id 为什么可以即等于零 又 不等于于零???
  2. fork()两个返回值是怎么回事???

问题1 涉及虚拟地址空间,我目前还没有了解。

那我们来看fork函数(由OS提供),在代码执行的过程中,子进程就已经存在了,可以被调度了。

在任何操作系统中,进程一定要做到:进程具有独立性 ,PCB = 内核数据结构task_struct +代码与数据(只读
那么如何查看该进程使用了哪些数据和代码呢???
使用ls /proc/pid -d就可以查到该进程的数据:
在这里插入图片描述
我们详细展开即可查看:
在这里插入图片描述
其中的exe 指向 是从什么路径下的文件加载的可执行程序。
在进程结束之后对应路径也会被销毁。

总结

  1. 进程 = 内核task_ struct结构体 + 程序的代码和数据
  2. ps ajx 可以查看我们的进程,为了方便演示我们使用grep 来进行一下筛选:ps ajx | grep myprogress
  3. PID : 每一个进程都要有自己的唯一标识符,叫做进程PID
  4. pid_t getpid() 获取pid
  5. 当我们多次运行时,每次进程PID都是不同的,但是父进程ID是相同的(每次运行 PID 不同是正常的)
  6. fork() 有两个返回值,父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝),创建一个进程,本质是系统中多一个进程,多一个进程,就是多一个内核task_struct ,父进程的代码和数据是从磁盘加载来的,子进程的代码和数据会默认进程父进程的代码和数据

送给大家一句话:

我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。。——山本耀司

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

相关文章:

【Linux】从零开始认识进程 — 前篇

我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。。——山本耀司 从零开始认识进程 1 认识冯诺依曼体系2 操作系统3 进程3.1 什么是进程&#xff1f;&#xff1f;&#xff1f;3.2 进程管理PCB 3.3 Linux中的进程深入理解 3.4 进程创建总结 送给…...

公众号留言功能恢复了,你的开通了吗?

了解公众号的人都知道&#xff0c;腾讯在2018年3月宣布暂停新注册公众号的留言功能&#xff0c;这之后注册的公众号都不具备留言功能。 这成了很多号主运营人的一块心病&#xff0c;也包括我。 没有留言&#xff0c;就好似一个人玩单机游戏&#xff0c;无法与读者互动&#xff…...

C语言葵花宝典之——文件操作

前言&#xff1a; 在之前的学习中&#xff0c;我们所写的C语言程序总是在运行结束之后&#xff0c;就会自动销毁&#xff0c;那如果我们想将一个结果进行长期存储应该如何操作呢&#xff1f;这时候就需要我们用文件来操作。 目录 1、什么是文件&#xff1f; 1.1 程序文件 1.2…...

SSM框架,MyBatis-Plus的学习(下)

条件构造器 使用MyBatis-Plus的条件构造器&#xff0c;可以构建灵活高效的查询条件&#xff0c;可以通过链式调用来组合多个条件。 条件构造器的继承结构 Wrapper &#xff1a; 条件构造抽象类&#xff0c;最顶端父类 AbstractWrapper &#xff1a; 用于查询条件封装&#xf…...

边缘计算网关的工作原理及其在工业领域的应用价值-天拓四方

随着物联网技术的快速发展&#xff0c;物联网时代已经悄然来临。在这个时代&#xff0c;数以亿计的设备相互连接&#xff0c;共享数据&#xff0c;共同构建智慧的世界。边缘计算网关通过将计算能力和数据存储推向网络的边缘&#xff0c;实现了对海量数据的实时处理&#xff0c;…...

下载指定版本的pytorch

下载网址&#xff1a;https://download.pytorch.org/whl/torch_stable.html 参考博客网址&#xff1a;https://blog.csdn.net/wusuoweiieq/article/details/132773977...

STL:List从0到1

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f648;个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…...

利用高分五号02星高光谱数据进行地物识别

高分五号02星搭载了一台60公里幅宽、330谱段、30米分辨率的可见短波红外高光谱相机&#xff08;AHSI&#xff09;&#xff0c;可见近红外&#xff08;400~1000nm&#xff09;和短波红外光谱&#xff08;1000~2500nm&#xff09;分辨率分别达到5纳米和10纳米。单看参数性能优越&…...

前端如何识别上传的二维码---jsQR

npm npm i -d jsqrhtml <el-button click"$refs.input.click()">识别</el-button> <input type"file" style"display: none" id"input" input"upload">js import jsQR from "jsqr";decodeQR…...

flink1.18.0 自定义函数 接收row类型的参数

比如sql中某字段类型 array<row<f1 string,f2 string,f3 string,f4 bigint>> 现在需要编写 tableFunction 需要接受的参数如上 解决方案 用户定义函数|阿帕奇弗林克 --- User-defined Functions | Apache Flink...

JDK8和JDK11在Ubuntu18上切换(解决nvvp启动报错)

本文主要介绍JDK8和JDK11在Ubuntu18上切换&#xff0c;以供读者能够理解该技术的定义、原理、应用。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;计算机杂记 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人…...

基于eleiment-plus的表格select控件

控件不是我写的&#xff0c;来源于scui,但在使用中遇到了一些问题&#xff0c;希望能把过程记录下来&#xff0c;同时把这个问题修复掉。 在使用的时候对控件进行二级封装&#xff0c;比如我的一个商品组件&#xff0c;再很多地方可以用到&#xff0c;于是 <template>&l…...

「❤️万文总结 时光回忆录❤️」那年,我在北京邮电大学计算机学院求学的日子

文章目录 关于我 | About Me梦绕西土城&#xff0c;邮情涌流 | Dreams and Connections in Haidian 北邮求学记 | My Days at BUPT岁月如歌&#xff0c;追忆往昔 | Reminiscing the Fleeting Years新篇章&#xff1a;班级与环境 | New Class, New Surroundings高压与挑战&#…...

【四 (1)数据可视化之如何选用正确的图表】

目录 文章导航一、数据分析中可视化的作用1、揭示数据关联和模式2、支持数据分析和决策3、提升沟通和共享效果4、强调关键信息和发现5、增强故事叙述和记忆效果6、有效增强数据交互性数据7、复杂信息易理解8、数据多维度显示 二、如何选用合适的图表1、简洁性避免使用过于复杂或…...

PHP<=7.4.21 Development Server源码泄露漏洞 例题

打开题目 dirsearch扫描发现存在shell.php 非预期解 访问shell.php&#xff0c;往下翻直接就看到了flag.. 正常解法 访问shell.php 看见php的版本是7.3.33 我们知道 PHP<7.4.21时通过php -S开起的WEB服务器存在源码泄露漏洞&#xff0c;可以将PHP文件作为静态文件直接输…...

大语言模型RAG-技术概览 (一)

大语言模型RAG-技术概览 (一) 一 RAG概览 检索增强生成&#xff08;Retrieval-AugmentedGeneration, RAG&#xff09;。即大模型在回答问题或生成问题时会先从大量的文档中检索相关的信息&#xff0c;然后基于这些信息进行回答。RAG很好的弥补了传统搜索方法和大模型两类技术…...

【嵌入式DIY实例】-DIY锂电池电压检测表

DIY锂电池电压检测表 文章目录 DIY锂电池电压检测表1、直流电压检测传感器介绍2、硬件准备3、代码实现4、OLED显示在电子应用中,通常需要使用到电池,电源管理是必不可少的部分。本文将详细介绍如何使用一个0-25V的直流电压传感器来检测锂电池的电压。 1、直流电压检测传感器介…...

生成baidu.com域名的私有证书:Linux系统命令示例

在Linux系统上生成一个针对xzyxdev.prec-tech.com域名的私有证书&#xff08;通常指的是自签名证书&#xff09;&#xff0c;你可以使用openssl工具。以下是一个简单的步骤和命令示例来生成这样的证书&#xff1a; 生成私钥 首先&#xff0c;你需要生成一个私钥。这通常是一个…...

小程序学习4 mock

services/home.js import { config, cdnBase } from ../../config/index;/** 获取首页数据 */ function mockFetchHome() {const { delay } require(../_utils/delay);const { genSwiperImageList } require(../../model/swiper);return delay().then(() > {return {swip…...

Unity3D MMORPG角色的UI血条管理详解

前言 在Unity3D游戏开发中&#xff0c;MMORPG&#xff08;Massively Multiplayer Online Role-Playing Game&#xff09;游戏是一种非常流行的游戏类型。在这种类型的游戏中&#xff0c;玩家通常可以选择不同的角色来进行游戏&#xff0c;而角色的血条管理是游戏中非常重要的一…...

【python】爬取杭州市二手房销售数据做数据分析【附源码】

一、背景 在数据分析和市场调研中&#xff0c;获取房地产数据是至关重要的一环。本文介绍了如何利用 Python 中的 requests、lxml 库以及 pandas 库&#xff0c;结合 XPath 解析网页信息&#xff0c;实现对链家网二手房销售数据的爬取&#xff0c;并将数据导出为 Excel 文件的过…...

Day34:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法

目录 Java-反射-Class对象类获取 Java-反射-Field成员变量类获取 Java-反射-Method成员方法类获取 Java-反射-Constructor构造方法类获取 Java-反射-不安全命令执行&反序列化链构造 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;…...

Transformer代码从零解读【Pytorch官方版本】

文章目录 1、Transformer大致有3大应用2、Transformer的整体结构图3、如何处理batch-size句子长度不一致问题4、MultiHeadAttention&#xff08;多头注意力机制&#xff09;5、前馈神经网络6、Encoder中的输入masked7、完整代码补充知识&#xff1a; 1、Transformer大致有3大应…...

安卓性能优化面试题 31-35

31. 简述Handler导致的内存泄露的原因以及如何解决 ?在Android开发中,Handler对象可能导致内存泄漏的主要原因是由于Handler持有对外部类对象的隐式引用,从而导致外部类无法被垃圾回收,进而引发内存泄漏。下面是导致Handler内存泄漏的几种常见情况及相应的解决方法: 1. 长…...

QML与C++通信

一、QML中如何使用C的类和对象 前提条件&#xff1a; 1.从 QObject 或 QObject 的派生类继承 2.使用 Q_OBJECT 宏 这两个条件是为了让一个类能够进入 Qt 强大的元对象系统&#xff08;meta-object system&#xff09;中&#xff0c;只有使用元对象系统&#xff0c;一个类的某些…...

Explain详解与索引优化最佳实践

Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在select语句之前增加explain关键字,MySQL会在查询前设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL 注意: 如果from中包含子查询,仍会执行该子查询,将结果…...

Spring Boot轻松整合Minio实现文件上传下载功能【建议收藏】

一、Linux 安装Minio 安装 在/root/xxkfz/soft目录下面创建文件minio文件夹&#xff0c;进入minio文件夹&#xff0c;并创建data目录&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data执行如下命令进行下载 [rootxxkf…...

MySql入门教程--MySQL数据库基础操作

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Slider)

滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Slider(options?: SliderOption…...

第五十六回 徐宁教使钩镰枪 宋江大破连环马-飞桨图像分类套件PaddleClas初探

宋江等人学会了钩镰枪&#xff0c;大胜呼延灼。呼延灼损失了很多人马&#xff0c;不敢回京&#xff0c;一个人去青州找慕容知府。一天在路上住店&#xff0c;马被桃花山的人偷走了&#xff0c;于是到了青州&#xff0c;带领官兵去打莲花山。 莲花山的周通打不过呼延灼&#xf…...