Linux---进程概念

目录

一、冯诺依曼体系结构

 二、操作系统

1.关于下三层的理解

2.关于上三层的理解

三、进程

1.进程(也叫做任务)对应的标识符---pid

 2.fork---用代码创建进程(系统接口)

1)初步认识一下fork 

2)fork函数的返回值

3)fork的原理

问题1: fork具体干了什么?

问题2: 为什么fork会有两个返回值?

问题3:为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?

问题4:fork之后,父子进程谁先运行?

问题5:如何理解同一个变量id,会有不同的值?


一、冯诺依曼体系结构

计算机都是由一个个的硬件组件组成

  • 输入设备:包括键盘、鼠标、扫描仪等
  • 中央处理器(CPU):含有运算器和控制器等
  • 输出设备:显示器、打印机等

注意:

  • 这里的存储器指的是内存
  • 不考虑缓存的情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入输出设备)
  • 外设要输入或者输出数据,也只能写入内存或者从内存中读取

总结:所有的设备都只能直接和内存打交道

上图是一个表示设备存储效率的金字塔图,根据木桶效应,我们会让效率相差不大的设备直接相连来保证相对高效的运行效率和相对较低的成本。

1.程序在被运行之前,得先加载到内存,为什么?程序(代码+数据)被运行,本质就是让CPU去执行,而CPU只和内存进行直接的数据交互,并且我们一般运行的程序都是exe文件,被存储在磁盘中,所以程序要被先加载到内存(体制结构决定)

2.如何理解网络信息之间的数据流动过程?(拿qq好友聊天举例)

 二、操作系统

1.是什么?是一款软件,进行软硬件资源管理的软件 (电脑开机先要打开操作系统)

2.为什么要有操作系统?操作系统将软硬件资源管理好(手段),给用户提供良好的(稳定,高效,安全)使用环境(目的)

3.怎么办?即如何实现

1.关于下三层的理解

  • 硬件部分是冯诺依曼体系结构。
  • 驱动程序---这个大家可能没怎么听过,但是我们都应该见过当插入U盘时,电脑会弹出一个U盘驱动程序启动类似的弹窗,那就是在运行驱动程序(不同的硬件有不同的驱动程序)。
  • 操作系统就是通过驱动程序来访问硬件资源的。

那么操作系统如何对软硬件资源进行管理?

这个其实可以类比现在学校的教务系统,学校对学生的管理本质是对学生的相关信息的管理,比方说,学校的校长并不了解每一个学生,但是他能对所有学生的学习情况了如指掌,为什么?因为他有你们每次考试的成绩数据,通过对这些数据的进行排序筛选等操作,他就能知道每个学生的学习情况,所以管理的本质是对数据进行管理

而如何记录学生相关数据,在计算机领域,显然就是用struct/class存放学生的基本信息等等,而对它们的管理,就是用相应的数据结构将数据连接组织起来,进行相应的增删查改的操作,所以总结一下就是六个字:先描述,在组织。

操作系统对硬件的管理也是如此,每个硬件都会有一个结构体对象用来描述该硬件的相关属性信息,再将它们用链表组织起来,这样对硬件的管理就变成了对链表的管理(当然也可能是其他的数据结构),所以一个硬件是否被管理,不在于它是否和电脑进行了物理连接,而在于操作系统中是否有一个结构体对象用来描述管理该硬件

2.关于上三层的理解

  • 用户---一般来讲指所有人,但是这里我们以开发者的视角来看待问题,因为操作系统如果对开发者都不提供服务,那么就没有所谓的软件应用给普通人使用
  • 用户调用接口和系统调用接口的存在是为了保护操作系统的安全

通过下三层的讲解,我们知道操作系统能访问硬件,那么我们用户能不能直接对操作系统进行操作以此来访问外设呢?

当然可以,但是我们不能保证用户的操作不会对操作系统造成影响甚至破坏,毕竟还是有恶意用户存在的,为此,操作系统提供了system call来防范用户的不合理的请求。


那么我们能不能绕过操作系统,直接对硬件进行访问呢?

这就有点类似于那种无人看管的图书馆,任何人都能进去借书,但是不做记录,因为没人管理,这座图书馆迟早出问题,同理,硬件也需要操作系统来进行统一的管理


那么为什么有用户操作接口呢?

因为系统接口用起来比较麻烦,不是所有人都能很好的使用系统接口,所以在system call之上还有用户操作接口,来简化用户的操作

外壳程序在Linux中是shell,在windows中是图形化界面。拿windows系统举个例子,当我们双击图标打开文件的时候,本质是调用系统接口打开文件,打开不同的文件要传的参数也不同,如果让你去选,你愿意双击还是敲系统接口,显然我们都喜欢双击。

各个语言的lib(标注库)也是如此,拿C语言举例,C标准库中的函数有很大一部分都是对系统接口进行了封装实现的,比如printf打印字符串到显示器,对于硬件的访问都是要经过操作系统的,所以别看我们只写了一行打印语句,底层还是封装的系统调用接口帮助我们实现的。库的实现,提高了开发的效率

三、进程

什么是进程?进程是正在执行的程序。

我们如何理解这句话?

进程=可执行程序+内核数据结构(pcb),对于"正在执行"的理解其实就是进程会在不同的状态之间切换,比如我们打开了很多进程,但不是每个进程都在一直被运行,而是用到它的时候就让它运行,不用的时候就让它等待(当然还有其他状态),看起来进程好像是动态的,本质还是对内核数据结构的操作


Linux中的PCB是struct task_struct{}

tast_struct中有哪些内容?

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

1.进程(也叫做任务)对应的标识符---pid

可以看见mytest的进程pid为22385,当然这个pid是会变化的,每次运行都不一样,这跟我们去排队,然后中途有事离开,再回来时需要重新排队是一个道理。

(感兴趣的可以用man ps去看看ps命令的介绍和其他选项)

(重新在运行程序后ps命令的截图) 

ppid是进程的父进程,mytest的父进程是bash命令行,bash命令行是一直在运行的,所以id不变 

Linux中启动进程的两种方式:1.手动输入命令行启动  2.通过代码创建进程启动

进程的启动本质是创建进程,一般通过父进程创建(如上,我们通过bash命令行解释器这个父进程创建mytest这个子进程),所以进程间有一种父子关系。

这里介绍获取pid和ppid的函数

除了ps命令,我们还可以通过 /proc 这个目录来查看进程的信息。

蓝色的数字就是进程的pid,我们可以运行一下自己的进程看看

当我们运行程序时,就会再/proc目录中创建相关的目录记录该进程信息,当我们结束进程时,对应的目录就会被删除。所以 /proc 是动态的目录结构,存放所有存在的进程,目录的名称,就是以这个进程的id命名的。


下面我们来看看这个目录中存放了些什么

这些文件都是进程的相关信息,我们暂不关心,我们主要看被框里来的两个。

第二个被框起来的部分是该程序在磁盘上的位置,也就是说,一个进程能找到自己的可执行程序。

在上面的操作中,我们先运行mytest,然后将mytest从磁盘上删掉。可以从该进程的目录下看到该进程知道自己被删除,但是却还在正常运行,为什么?在之前我们就说过,进程的创建要先将程序加载到内存,所以我们运行的是内存中的mytest程序,磁盘上的mytest删除并不会影响内存中的程序运行。


cwd---当前目录,这个大家在学C语言的文件操作的时候,应该就听过这个概念

//fopen函数的第一个参数如果传的是相对路径,就会在该路径前面加上cwd
//这就是为什么我们创建的文件一般都在项目所在的目录下,
//一般我们默认的当前目录都是进程启动所处的路径
fopen("test.txt","w");

当然这个当前路径是可以改变的,用下面这个函数

int chdir(const char *path);

 2.fork---用代码创建进程(系统接口)

启动进程,本质是在系统中创建一个进程,操作系统管理的进程多一个,而进程=可执行程序+内核数据结构(task_struct对象),所以创建进程,就是申请内存空间保存可执行程序+task_struct对象,并将tast_struct对象添加到进程队列中。

1)初步认识一下fork 

fork可以用来创建进程,如下 

第二个打印语句被执行了两次,且它们pid不同,那么我们来看看这两个进程的ppid分别是什么。

现象:mytest的父进程是bash,新创建的进程的父进程为mytest,所以fork函数用来创建子进程,且子进程只执行fork之后的语句,前面的语句不执行

(可以推断出bash命令行创建子进程用的就是fork函数)

2)fork函数的返回值

fork函数的返回值不同,这很难理解,但是我们根据现象可知,在父进程中返回子进程的pid,在子进程中返回0,当然如果创建进程失败,返回-1

这里要说明一下创建子进程的意义是什么,创建子进程是为了辅助父进程完成工作,而不是为了和父进程执行一样的操作,所以我们一般是这样用fork的

用if-else语句将父子进程要做的事情分流,所以我们需要有两个返回值来分辨这两个进程

3)fork的原理

在上面的演示,其实我们还有很多问题没有讲清楚

  1. fork具体干了什么?
  2. 为什么fork会有两个返回值?
  3. 为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?
  4. fork之后,父子进程谁先运行?
  5. 如何理解同一个变量id,会有不同的值?
问题1: fork具体干了什么?


问题2: 为什么fork会有两个返回值?

在之前我们就说过fork是用来创建子进程的,那么fork创建子进程实在最后一句return语句之后才彻底完成的吗?显然不是,创建子进程的工作一定在return之前就已经完成了,所以在return之前,父子进程就已经开始共享数据和代码执行相关语句,当然fork的return也在其中,所以fork会有两个返回值


问题3:为什么fork的两个返回值,给父进程返回子进程的pid,给子进程返回0?

因为一个父进程可以创建多个子进程,而一个子进程只能有一个父进程,所以父进程需要知道子进程的id来分辨子进程,而子进程不需要,因为它只有一个父进程


问题4:fork之后,父子进程谁先运行?

这个是不确定的,当创建了子进程后,父子进程都需要在运行队列中排队,哪一个进程的pcb先被选择调度,哪个进程就先运行(具体由pcb中的调度信息和调度器算法共同决定,可以理解为由操作系统决定)


问题5:如何理解同一个变量id,会有不同的值?

当我们终止子进程/父进程时,会不会影响另一个进程的运行?

所以任何一个进程都具有独立性,但是我们知道父子进程的代码和数据是共享的,它怎么保证互不影响呢?首先代码是只读的,不可修改,那么数据呢?

在父子进程运行的过程中,我们都会用到数据,如果某些数据会被两个进程同时影响会导致代码逻辑出现问题,所以操作系统会让进程的数据各自"私有",当然这个不是说就完全拷贝一份给子进程,而是通过写时拷贝(就是在写入时才会出现拷贝)实现的,这样会减少空间浪费。

而fork函数的返回值给id这个变量,本质就是数据写入,会出现写实拷贝,所以id会有两个值

但其实我们还不能完全解释这个现象

看上图,我们会发现id这个变量的地址是一样的,但是一样的地址却有两个不同的值,这不可能,所以我们能确定这个地址不是真正的物理地址!!!(具体在进程空间再讲)

未完待续……

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

残差网络中的BN (Batch Normalization 批标准化层)的作用是什么?

文章目录 什么是BN (Batch Normalization 批标准化层)一、BN层对输入信号进行以下操作:二、BN 层有什么作用? 什么是BN (Batch Normalization 批标准化层) BN层的全称是Batch Normalization层,中文可以翻译为批标准化…

[Big Bird]论文解读:Big Bird: Transformers for Longer Sequences

文章目录 1 介绍2 模型架构3 结果 论文:Big Bird: Transformers for Longer Sequences 作者:Manzil Zaheer, Guru Guruganesh, Avinava Dubey, Joshua Ainslie, Chris Alberti, Santiago Ontanon, Philip Pham, Anirudh Ravula, Qifan Wang, Li Yang, Am…

多维时序 | MATLAB实现RIME-LSSVM【23年新算法】基于霜冰优化算法(RIME)优化最小二乘向量机(LSSVM)多变量时间序列预测

多维时序 | MATLAB实现RIME-LSSVM【23年新算法】基于霜冰优化算法(RIME)优化最小二乘向量机(LSSVM)多变量时间序列预测 目录 多维时序 | MATLAB实现RIME-LSSVM【23年新算法】基于霜冰优化算法(RIME)优化最小二乘向量机(LSSVM)多变量时间序列预测预测效果基本介绍模型描述程序设…

【最新版】在WSL上运行 Linux GUI (图形用户界面)应用(Gnome 文本编辑器、GIMP、Nautilus、VLC、X11 应用)

文章目录 一、 安装WSL1. 全新安装2. 现有 WSL 安装 二、运行 Linux GUI 应用1. 更新发行版中的包2. 安装 Gnome 文本编辑器启动 3. 安装 GIMP启动 4. 安装 Nautilus启动 5. 安装 VLC启动 6. 安装 X11 应用 适用于 Linux 的 Windows 子系统 (WSL) 现在支持在 Windows 上运行 Li…

深入比较Input、Change和Blur事件:Vue与React中的行为差异解析

目录 前言 1. Input事件: 行为差异: 2. Change事件: 行为差异: 3. Blur事件: 行为差异: 4. 在Vue中的表现: Input事件: Change事件: Blur事件: 5.…

Quartus 18.1软件及支持包安装教程

安装前最好关闭电脑的杀毒软件和防火墙 安装包可以到Quartus官网下载需要的版本,注意选择操作系统 Quartus官网:FPGA 设计软件 - 英特尔 Quartus Prime (intel.cn) 下载解压后以管理员的身份运行 QuartusSetup-18.1.0.625.exe文件,版本不同…

Vue中的数据变化监控与响应——深入理解Watchers

目录 ​编辑 前言 1. 基本用法: 2. 深度监听: 3. 立即执行: 4. 监听多个数据: 5. 清理监听器: 6. 监听路由变化: 总结: 我的其他博客 前言 在Vue.js中,watch是一种用于监听…

【Spring】Spring中的事务

文章目录 1. Spring事务简介2. Spring事务的案例案例代码代码目录结构数据库pom.xmlResource/jdbc.propertiesconfig/SpringConfig.javaconfig/JdbcConfig.javaconfig/MyBatisConfig.javadao/AccountDao.javaservice/AccountService.javaservice/impl/AccountServiceImpl.java测…

设计模式 简单工厂 工厂方法模式 抽象工厂模式

工厂模式介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。它是创建型模式。 简单工厂 简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例, 但它不属于GOF 23种设计模式 简单工厂适用于工厂类负责创建的对象较少的场景,…

Command line is too long. Shorten command line for Application or also

一、问题描述 Error running ‘Application’: Command line is too long. Shorten command line for Application or also for Spring Boot default configuration? 二、原因分析 springboot项目启动命令过长! 三、解决方案 第1步:点击项目启动配置项 第2步…

基于ssm的简单学校课程管理系统的设计与实现(源码+调试)

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于ssm的简单学校课程管…

vue2项目vue-qrcode-reader 扫一扫二维码插件

vue2项目 vue-qrcode-reader 扫一扫二维码插件 问题所在解决办法成功展示 问题所在 今天在引导师弟做扫二维码功能,发现通过npm install --save vue-qrcode-reade安装死活就是报错TypeError: Object...) is not a function 解决办法 百度了很多大牛的博客&#…

国内访问GitHub很卡,steam连接断开怎么办

目录 第一章、问题分析1.1)问题1.2)解决:下载个加速器就好了 友情提醒: 先看文章目录,大致了解文章知识点结构,点击文章目录可直接跳转到文章指定位置。 第一章、问题分析 1.1)问题 国内访问GitHub很卡怎…

数据分析(一)(附带实例和源码)

一、主要目的: 主要利用Python包,如Numpy、Pandas和Scipy等常用分析工具并结合常用的统计量来进行数据的描述,把数据的特征和内在结构展现出来。熟悉在Python开发环境中支持数据分析的可用模块以及其中的方法,基于一定的样例数据…

Windows中安装Git软件和TortoiseGit软件

1、git软件下载地址 https://git-scm.com/download/win 2、TortoiseGit软件下载 >https://tortoisegit.org/download/ 3、软件安装 4、环境安装说明 上面介绍的是在Windows中使用git,如果你电脑已经装了Ubuntu系统,可以直接在Ubuntu中使用git命令提…

arthas获取spring bean

参考文章 arthas获取spring bean 写一个工具Util package com.example.lredisson.util;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import o…

[RK-Linux] 移植Linux-5.10到RK3399(七)| 检查GPIO与LED节点,使能风扇接口

文章目录 一、原理图二、设备树配置三、节点控制一、原理图 ROC-RK3399-PC Pro 的 LED 接口如图: 工作灯 WORK_LED (蓝色灯)网络连接到 GPIO2_D3: DIY_LED (红色灯)网络连接到 GPIO0_B5: ROC-RK3399-PC Pro 要控制的 GPIO 接口主要是风扇,如图: FAN_CTL 网络连接到

【Java】SpringBoot中实现Redis Stream队列

SpringBoot实现Redis Stream队列 前言 简单实现一下在SpringBoot中操作Redis Stream队列的方式,监听队列中的消息进行消费。 jdk:1.8 springboot-version:2.6.3 redis:5.0.1(5版本以上才有Stream队列)…

【C++】STL 容器 - string 字符串操作 ⑤ ( string 字符串查找 | find 函数查找字符串 | rfind 函数查找字符串 )

文章目录 一、string 字符查找 - find 函数查找字符串1、string 类 find 函数原型说明2、代码示例 - 字符串查找3、代码示例 - 统计字符串子串 二、string 字符查找 - rfind 函数查找字符串1、string 类 rfind 函数原型说明2、代码示例 - rfind 字符串查找 一、string 字符查找…

前端常用去重的几种方式

文章目录 方式1: ES6新语法方式2: 遍历 利用filter方式3: 使用 new Map() for循环方式4: 利用 hasOwnProperty总结 在github 查看该文章 方式1: ES6新语法 过滤出网页中不重复的html标签 结合去重知识点考查 […new Set([…document.querySelectorAll(‘*’)].map(v>v.t…