计算机是如何工作的(下)

4. 编程语言(Program Language)

       本块内容主要是还原下我们已经熟悉的编程语言,即编程语言是如何和 CPU 指令对应起来的。

4.1 程序(Program)

        所谓程序,就是一组指令以及这组指令要处理的数据。狭义上来说,程序对我们来说,通常表现为一组文件。

        即程序 = 指令 + 指令要处理的数据

4.2 早期编程 

        最早的电脑,要进行编程,是真的需要用 0、1进行编程的, 下面图给大家展示了 Altair 8800 计算机,是最早的一批微型电脑。用户需要控制开关,一个一个 bit 的 将程序录入该电脑中。

           

        如果要求计算机的用户都必须使用二进制编程,那大家都要疯掉了,这可是一件门槛太高的事情了。所以编程语言应运而生了。

4.3 编程语言发展

        为了提升编程效率,最早创造了汇编语言的概念。其实汇编语言和机器语言(也就是指令)直接是完全一一对应的,只是相对于 0、1 这些数字,发明了一些帮助人类记忆和理解的符号将其对应起来,也就是我们上面看到的类似 LOAD_A、LOAD_B 等。程序员完成编程之后,需要使用汇编器(assembler)

        将汇编语言翻译成机器语言。虽然汇编降低了程序员的记忆成本,但要求程序还是必须掌握计算机硬件的所有知识,而且随着计算机厂商越来越多,一次编写的程序往往只适用于一类计算机。

        这个是远远不够的,所以更为高级的语言诞生了,高级语言屏蔽了硬件细节,让程序员可以站在更高的层面上思考自己的业务。

        这里以 C 语言为例,程序员完成程序的编写之后,需要使用编译器(compiler)和连接器(linker)将程序翻译成汇编语言,再借助汇编器变成最终的机器语言。

        借助封装的思想,我们学习编程变得越来越容易。不过有利则有弊,高度的抽象,导致很多的程序员把计算机视为一个黑箱,完全无法理解自己的程序是如何工作起来的,希望我们大家不要做这种程序员。

        我们使用的 Java 语言相对于 C 语言更高级一点,但基本抽象原理上没有太大的差异,这里就暂时就不展开说明了。且编程语言的历程如下图所示:

        注意:高级语言的一条语句(Statement)往往对应很多条指令(Instruction)才能完成

5. 操作系统(Operating System)

        需要时刻注意,操作系统的核心概念就是进程;

        操作系统是一组做计算机资源管理的软件的统称,即操作系统是一个软件-(由代码构成程序)。

     操作系统的主要职责,有两方面:

  1. 管理各种硬件设备
  2. 给其他软件提供稳定的运行环境。->抽象封装的作用

     如此,程序员写的代码不需要面向硬件,只需要面向操作系统即可;Jvm又是对系统的抽象封装,所以java程序员只用jvm提供的api就可以起到控制各种不同的系统,完成编程的作用。

        目前常见的操作系统有:Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等

5.1  操作系统的定位

        

        操作系统由两个基本功能(官方用语):

  1. 防止硬件被时空的应用程序滥用;(管理各种硬件设备

  2. 向应用程序提供简单一致的机制来控制复杂而又通常大相径庭的低级硬件设备。(给其他软件提供稳定的运行环境

5.2 什么是进程/任务(Process/Task)

        进程就是操作系统提供的一种“软件资源”;

        咱们现在所使用的操作系统,就属于“多任务操作系统”,->即同一时刻,可以同时运行多个任务(同一时间,使用qq音乐,word,浏览器等),这些正在运行中的程序,就可以称为是“任务”,也叫做进程

        与之对应的就是“单任务操作系统”,同一时刻,只能运行一个程序。单任务系统,没有后台执行,想要执行另外一个程序,就需要把之前的那个程序退出。单任务的操作系统十分不便利,多任务操作系统,是当前的主流方式之一。·

         如上图所示,我们同一时刻使用多个应用软件,每一个软件执行的当前任务就是一个进程;

        如下图所示,上图中的每个任务在执行的过程中,都需要消耗一定的硬件资源。->即可以认为,计算机的每个进程,在运行的过程中,都需要给他分配一定的系统资源(进程是系统分配资源的基本单位),下图是当前多个进程执行的时候所需要耗费的硬件资源;

        下面我们需要知道,进程在系统中是如何管理的? 

5.3 操作系统的进程管理

        1. 先描述(使用类/结构体这样的方式,把实体属性给列出来)

        操作系统一般都是c/c++实现的(没有用java写的),因此就可以使用结构体,表示进程信息的结构体,PCB(进程控制块,Process Control Block),是操作系统学科中的通用概念,windows上表示进程的结构,也可以称为PCB,linux也可以称为PCB

        2. 在组织(使用一定的数据结构,把这些结构体/对象,串到一起)(数据库->表格)

        在linux中,使用链表这样的数据结构把若干个task_struct给串起来;当我们看到任务管理器中的这些进程的时候,意味着系统内部就在遍历链表,并且打印每个节点的关键信息;

         如果运行一个新的程序,于是系统中就会多一个进程,多的这个进程就需要构造一个pcb,然后添加到链表上。如果某个运行的程序退出了,就需要把对应进程的pcb从链表中删除,并且销毁对应的pcb资源。有的程序是带有驱动的,这些驱动是在系统“内核”中执行的,这里出现的问题可能会导致系统卡死或蓝屏。

5.3.1Pcb中的核心属性

        (pcb这个结构体,是一个非常庞大的结构体)

        1. pid:

        进程的身份表示(此处通过一个简单不重复的整数来进行区分的),操作系统会保证同一个机器上,同一时刻,每一个进程的pid都是唯一的(后序要针对某个进程进行操作,就可以拿着pid进行区分了)

        比如,选中某个进程,并且点击结束任务,此时,就是任务管理器获取到你选中的进程的pid,然后调用一个系统api,把pid作为参数穿进去,从而完成这里杀死进程的操作。

        2. 内存指针(一组

        就是用来描述上述所说的这个进程跑起来所使用的那些资源,进程运行过程中,需要消耗一些系统资源的,其中内存就是一种很重要的资源。整个系统,内存这么多(16G),这16G不可以随意使用:

            先从系统这里申请,系统分配给你一块,才能使用。每个进程都必须使用自己申请到的内存。故此内存指针,就是用来描述你说的这个进程,都能使用那些内存。

        一个进程跑起来的时候,需要有指令,也需要有数据(指令和数据,都是要加载到内存中的去的),进程也需要知道哪边存的是指令哪里存的是数据。

            eg:双击一个exe,就会“运行进程”,这个过程中,就是系统先把exe这个文件里面的内容(包含指令和数据),先加载到内存中,然后在创建进程,让进程开始执行。->指令一般不是很大,但是数据一般很大。

        3. 文件描述符表:(描述了这个进程,所涉及的硬盘相关的资源)

        我们的进程经常要访问硬件。操作系统,对于硬盘这样的硬件设备,进行了封装-------------->文件存储器=内存+外存(硬盘,软盘,光盘)

        我们的操作系统,不管哪种盘,都是统一进行的抽象,都是按照“文件”的方式来操作的。 一个进程要想操作文件,需要先“打开文件”(就是让你的进程在文件描述符表中分配一个表项(构造一个结构体),来表示这个文件的相关信息)

        番外:        

        1、进程是系统分配资源的基本单位(内存,硬盘->都会在pcb中有所体现),一个进程,消耗cpu的资源是啥意思?

        进程就是执行指令,有的电脑的cpu有16个逻辑核心,但是系统上的进程远远大于16个,所以这就涉及到了分时复用(并发);

        2、单个核心的cpu,能否支持“多任务操作系统”运行呢?

         可以,虽然cpu核心只有一个,先执行进程1的代码(进程一,登台演出),执行一会后,让进程1下来,进程二上;进程二上执行了一段时间后,进程三上。。。。。。

        只要切换速度足够快,认识感知不到这个切换的过程的,在人眼看起来,多个任务/进程,就是“同时执行的”(cpu的频率都是多少ghz,即1s执行几十亿条指令,意味着短时间内,cpu就可以进行很多次的任务切换,只要速度够快,人就感知不到)

        后来,随着多核cpu诞生,pcb就开始同时执行进程。称为“并发执行,但是每个核心仍然要时分复用,要快速切换”

        当代的计算机执行过程,往往是并行+并发同时存在的。-->故此,往往把并行和并发统称为并发。所以,对应的编程模式,(解决一个问题,同时搞多个任务来执行,共同协作解决)就称为“并发编程”

        3、cpu占用率解释?

        此时,cpu的百分数,就是你的进程在cpu舞台上消耗的时间的百分比。如果有一个进程,把cpu吃到了100%,意味着其他进程都没有执行的时间了,这个进程就把cpu霸占了,就可能会造成系统卡顿。

    进程的调度,分时复用,并发执行。

 5.3.2 Pcb中的属性

        Pcb中就需要提供一些属性,来支持系统完成对这些进程的调度。

1、状态:某个进程能否去cpu上执行,有的时候,某个进程在某一时间不太方便去cpu上执行,(比如,某个进程需要通过用户scanner输入内容,但是不确定用户啥时候输入,于是这个进程就变得不可控),所以进程的状态分为以下几种:

    就绪状态:随时准备好去cpu上执行(操作系统一打招呼,就上了)

    阻塞状态:这个进程不方便去cpu上执行,不应该去调度他(比如,进程在等待io,来自控制台的输入输出/硬盘的输入输出/网卡输入输出)

    其他的状态不做过多展开

2、优先级:多个进程等待系统的调度,多个进程调度的先后关系,不是很平均。有些系统api是可以设置优先级的

3、记账信息:针对每个进程,占据了多少cpu时间,进行一个统计,会根据这个统计结果来进一步的调整调度的策略。因此在下一个轮次进行调整,确保让每个进程都能被cpu所执行。

4、上下文:(pcb中的数据结构,在内存中)支撑进程调度的重要属性,类似于游戏中的存档和读档。每个进程在运行过程中,就会有很多的中间结果,在cpu的寄存器中。(操作系统的调度进程,过程可以认为是随机的,任何一个进程,代码执行到任何一条指令的时候都可能被调度出cpu,在进程下次调度会cpu的时候,继续之前的进度来执行)

5、存档:因此,就需要在进程调度出cpu之前,把当前寄存器中的这些信息,给单独存到一个地方。

        读档:在该进程下次再去cpu上执行的时候,再把这些寄存器的信息给回复回来。

所谓的“保存上下文”就是把cpu的关键寄存器中的数据,保存到内存中(pcb的上下文属性中)

所谓的“恢复上下文”就是把内存中的关键寄存器中的信息,加载到cpu的对应寄存器中。

         以上绿色部分其实都是数据结构

5.4 内存分配 —— 内存管理(Memory Manage) 

        进程如何管理内存其实是一个十分复杂的问题:

        核心结论:每个进程的内存,是彼此独立,互不干扰的->(这个情况被称为系统的独立性)

      (通常情况下,进程A不能直接访问进程B的内存)-->为了系统的稳定性,如果某个进程代码出bug(比如内存写越界),这样出错影响的范围,只是影响到自己这个进程,不会影响到其他进程。如果系统上一个进程崩溃,从而影响到其他进程,无疑是一个非常糟糕的体验。

5.5 进程间通信(Inter Process Communication)

        虽然进程之间的独立性,但是有时候也需要,多个进程相互配合,完成某个工作。

进程间通信和进程的“独立性并不冲突,系统提供的一些公共的空间(多个进程都能访问到的),让两个进程借助这种公共空间来交换数据”

        

        目前,主流操作系统提供的进程通信机制有如下:

  1. 管道

  2. 共享内存

  3. 文件

  4. 网络

  5. 信号量

  6. 信号

        一般来说,我们主要使用的进程间通信方式是上述的三和四通信进制,网络,是可以支持同一个主机的不同进程,也能支持不同主机的不同进程。

        上述只是对于进程的讨论,实际上再java中,不太会使用“进程”,线程更为重要

            线程是线程实际开发中,是十分常用的机制;

        多任务操作系统:希望系统能够同时运行多个程序。引入进程本质上来说,就是解决“并发编程”这样的问题的。一般有些场景下,需要频繁的创建和销毁进程的时候,此时使用多进程编程,就会开销非常大。

        进程是资源分配的基本单位(一个进程,刚刚启动的时候,首先就是内存资源进程需要把依赖的代码和数据,从磁盘加载到内存中),从系统分配一个内存,并非是一个容易得事(一般来说,申请内存的时候,就需要指定一个大小,系统内部就把各种大小的空闲内存,通过一定的数据结构给组织起来了,实际申请的时候,就需要去这样的空间中进行查找,找到大小合适的空闲内存,分配过来),我们都知道,进程的调度是“分时复用的”,进程消耗的内存,也是在内存空间上“分时复用的;但是当前没在运行的进程,所消耗的内存空间,可以暂时不必正真放到“内存”上,可以暂时放到硬盘的特定区域(swap区域),等到进程真正执行的时候,再把这些内存数据装载进去,这样就可以有效的保证正在运行的进程内存比较充裕。”

        虚拟内存:是进程独立性的底层支撑

        结论:进程在进行频繁的创建和销毁的时候,开销比较大(主要体现在资源的申请和释放上)        

ps:本次的学习就到这里了,如果感兴趣的话就请一键三连哦!!!

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

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

相关文章

【数据结构入门精讲 | 第十四篇】散列表知识点及考研408、企业面试练习(1)

在上一篇中我们进行了树的专项练习,在这一篇中我们将进行散列表知识点的学习。 目录 概念伪代码线性探测法平方探测法查找成功的平均查找长度查找失败的平均查找长度判断题选择题 概念 散列表(Hash Table),也被称为哈希表或散列映…

向量投影:如何将一个向量投影到矩阵的行向量生成子空间?

向量投影:如何将一个向量投影到矩阵的行向量生成子空间? 前言 本问题是在学习Rosen梯度投影优化方法的时候遇到的问题,主要是对于正交投影矩阵(NT(NNT)-1N)的不理解,因此经过查阅资料,学习了关于向量投影的知识&…

嵌入式硬件电路原理图之跟随电路

描述 电压跟随电路 电压跟随器是共集电极电路,信号从基极输入,射极输出,故又称射极输出器。基极电压与集电极电压相位相同,即输入电压与输出电压同相。这一电路的主要特点是:高输入电阻、低输出电阻、电压增益近似…

Ubuntu:VS Code上C++的环境配置

使用 VSCode 开发 C/C 程序 , 涉及到 工作区的.vscode文件夹下的3个配置文件(均可以手动创建) : ① tasks.json : 编译器构建 配置文件 ; ② launch.json : 调试器设置 配置文件 ; ③ c_cpp_properties.json : 编译器路径和智能代码提示 配置文件 ;…

爬虫工作量由小到大的思维转变---<第二十三章 Scrapy开始很快,越来越慢(医病篇)>

诊断篇https://blog.csdn.net/m0_56758840/article/details/135170994?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170333243316800180644102%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id1703332433168001806441…

JavaOOP篇----第十四篇

系列文章目录 文章目录 系列文章目录前言一、Hashcode的作用二、Java的四种引用,强弱软虚三、Java创建对象有几种方式?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码…

mac m1芯片 pytorch安装及gpu性能测试

pytorch 使用mac的m1芯片进行模型训练。 #小结:在数据量小和模型参数少,batch_size小时,cpu训练更快(原因:每次训练时数据需要放入GPU中,由于batch_size小。数据放入gpu比模型计算时间还长&#xff09…

SpringIOC之AbstractMessageSource

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

K8S 外部访问配置、 Ingress、NodePort

将K8S部署应用提供给外部访问一般有三种方式: NodePort 暴露端口到节点,提供了集群外部访问的入口LoadBalancer 需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)Ingress 统一管理 svc的外部访…

Bloom过滤器

Bloom过滤器 一、概述二、原理三、优缺点1. 优点2.缺点 四、Bloom过滤器在比特币中的应用五、项目应用步骤1. pom.xml引入依赖2. 样例代码 六、Java版简易实现 一、概述 Bloom过滤器是一个允许用户描述特定的关键词组合而不必精确表述的基于概率的过滤方法。它能让用户在有效搜…

详解Vue3中的内置组件(transition)

本文主要介绍Vue3中的内置组件(transition)的普通写法和setup写法。 目录 一、在普通写法中使用内置组件(transition)二、在setup写法中使用内置组件(transition)三、使用注意项 在Vue3中,内置了…

Linux poll 和 select 机制

poll select 介绍 使用非阻塞 I/O 的应用程序常常使用 poll, select, 和 epoll 系统调用. poll, select 和 epoll 本质上有相同的功能: 每个允许一个进程来决定它是否可读或者写一个 或多个文件而不阻塞. 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来 读或写.…

Nessus详细安装-windows (保姆级教程)

Nessus描述 Nessus 是一款广泛使用的网络漏洞扫描工具。它由 Tenable Network Security 公司开发,旨在帮助组织评估其计算机系统和网络的安全性。 Nessus 可以执行自动化的漏洞扫描,通过扫描目标系统、识别和评估可能存在的安全漏洞和弱点。它可以检测…

使用 Spring Boot + MyBatis开发需要注意的事项以及开发模版

前言: 注意,本篇不适用于有相关开发经验的开发者,作为一个在职开发者,我经常在完成从0-1的模块,也就是从数据库表开始到创建实体类,以及dao层,Service层等业务需要添加相关注解,这样…

使用office打开word文档时候提示错误:0x426-0x0的解决方案

在使用office打开word文档时候提示错误:0x426-0x0。如下图: 昨天还用的好好的,怎么今天就不行了?为什么呢? 更多工作中遇到问题见:凯哥BK 这个错误导致office无法启动通常是由于office软件所依赖的服务无…

vue的表单收集案例

Vue的表单收集案例 这只是最基础的表单收集&#xff0c;并未涉及到element-ui。 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>收集表单数据</title><script type"text/javascript" src"../js…

Hago 的 Spark on ACK 实践

作者&#xff1a;华相 Hago 于 2018 年 4 月上线&#xff0c;是欢聚集团旗下的一款多人互动社交明星产品。Hago 融合优质的匹配能力和多样化的垂类场景&#xff0c;提供互动游戏、多人语音、视频直播、 3D 虚拟形象互动等多种社交玩法&#xff0c;致力于为用户打造高效、多样、…

物理模拟重力 斜抛运动计算 抛物线计算

物理模拟重力 斜抛运动计算 抛物线计算 一、介绍二、原理三、实现如下PhysicsUtil.cs 工具类Missile.cs 四、资源分享 一、介绍 模拟Unity原始重力系统进行重写&#xff0c;可是实现发射到指定目标位置并能继续当前力进行自身的弹力与摩擦继续运动 二、原理 将Unity原始不受控…

word2003 open word2007+

Win 7 C:\Documents and Settings\Administrator\Application Data\Microsoft\Templates 还是不行&#xff0c;重装office2003吧&#xff0c;再安装转换插件&#xff0c;但是再高版本好像没转换工具

【Linux】进程管理

ps&#xff1a;报告当前进程快照。top&#xff1a;显示任务。kill&#xff1a;给一个进程发送信号。shutdown&#xff1a;关机或重启系统。 一个程序可以发动另一个程序被表述为一个父进程可以产生一个子进程&#xff0c;内核维护每个进程的信息&#xff0c;以此来保持事情有序…