计算的需求在人类的历史中是广泛存在的,发展大体经历了从一般计算工具到机械计算机到目前的电子计算机的发展历程。人类对计算的需求,驱动我们不断的发明、改善计算机。目前这个时代是“电子计算机”的时代,发展的潮流是:更快速、更稳定、更微型。计算机的以后将如何发展,期待大家的努力。
🌈现代的计算机 , 大多遵守 冯诺依曼体系结构,如下图所示:
存储器:
输入设备: 用户给计算机发号施令的设备,如鼠标、键盘等
输出设备: 计算机给用户汇报结果的设备,如显示屏等
🌈CPU(Center Process Unit )全称是中央处理器,由ALU + CU + 寄存器 + 时钟组成,一般电子计算机中的cpu依靠背后的一个时钟来进行周期驱动。
衡量CPU的重要指标(当然远远不止这两个啦):
这两个值越高说明CPU越好,因此我们也可以通过这些来提升CPU 的性能
这里我们就不过多详细讲解,就做个大概了解就行
操作系统是一组做计算机资源管理的软件的统称。
操作系统 = 内核+配套的应用程序,其中内核是操作系统最核心的功能,系统的驱动程序都是在系统内核中执行的
目前常见的操作系统有:Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等。
内核的功能就是
操作系统由两个基本功能:
操作系统通过抽象封装来管理各种硬件,并给应用程序提供API(接口)和 稳定的运行环境。
每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一。
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。
进程是操作系统对于程序运行过程的描述,而这个描述学名叫作 进程控制块-PCB,它是操作系统管理以及调度程序运行的唯一实体,用来描述进程的属性。
在系统中一般会采取双向链表这样的形式来管理PCB,创建新的进程就是创建 PCB 然后把 PCB 插入到链表中,销毁进程,就是把 PCB 从 链表上删除并是否,展示进程列表,就相当于遍历链表的每个节点。
操作系统利用类/结构体的方式对进程的抽象表示,即名称为PCB的类/结构体。它非常庞大,有上百个属性。注:在Linux 中 PCB 我们一般叫作 task_struct
注:后面四点是用来完成 进程的调度(下文我们会单独介绍)
1.先描述:先利用类或结构体把进程中的实体属性列出来,即PCB。
2.再组织:通过一定的数据结构(链表)把这些结构、对象串在一起。
内存管理:每个进程的内存彼此独立,互不干扰,通常情况下,进程A不能直接访问进程B的内存(系统稳定性)
🍊早期的操作系统是一个 “单任务操作系统”,同一时刻只有一个进程能运行,然后要运行下一个进程,就会退出上一个(此时就不用考虑调度)
💢 而现在单任务已经满足不了我们的要求,太不方便了,因此计算机同时存在多个要执行的进程,CPU的每个核心可以执行一个进程(也就是执行里面的指令),但是一台机器CPU拥有的核心数量有限,但是却要执行几乎上百个进程,怎么办?
举个例子🌰: 就比如演个话剧,很多演员需要上去演,但是为了方便和好看,那么就会采用轮流上去演的方式,每个演员腌一会就下了,腾出地方,给其他演员去演。
进程调度解决了以上问题:分时复用,然后我们再来了解两个概念
🔥 上述 并发 和 并行 都是处于应用程序这一层,感知不到,都是在系统内部来完成调度的。我们一般也不会具体去区分 并发 和 并行,从编程角度来说,底层是并发还是并行对代码豆没啥影响,平时也就统一 使用 并发 来代指 并行 和 并发,并发编程。
因此由上面我们就可以 知道一个系统中可有这么多进程,也就是 并发编程 的效果。
下面这些属性,就是用于支持并发执行这个调度过程
(1)进程状态,包括以下5个
(2)进程优先级:进程调度时,有的进程先执行,有的进程后执行,这就是优先级
(3)进程上下文:分时复用,一个进程执行一段时间,就要从CPU上调度走,过一段时间又回来,此时需要沿着上次执行的结果继续执行,这个进程离开时,之前执行的中间结果会被相应的寄存器保存起来,用于下次使用,寄存器中保存起来的就叫进程的上下文。可以理解为:打游戏的存档~~当你游戏玩累了,不想玩了,此时可以存档,等下次你再想玩的时候直接读档即可
(4)进程的记账信息:在有优先级的前提下,不同的进程利用的系统资源是不一样的,操作系统会统计每个进程在CPU上执行的时间、内存使用情况等,根据这个记账信息,操作系统会进一步调整调度策略,做出优化,确保资源足够让每个进程正常执行
🔥 🔥早期的操作系统,程序运行时分配的内存就是物理内存,后面逐渐引入了 “虚拟地址空间” 这一概念,而不是直接去分配物理内存了,通过分配虚拟的内存空间,操作系统对于内存又进行了一层抽象。如下:
进程间通信🥬:
🍅通过上述方式,就可以把进程之间隔离开了,但是进程之间很多时候也需要相互配合完成某项工作,进程间通信和进程的独立性 并不冲突,系统提供公共空间(多个进程都能访问到),让两个进程借助这种公共空间来交互数据。
主要的通信方式:管道,共享内存,文件,网络,信号量,信号等。
🍅多进程来实现并发编程,效果的确非常好,但是多进程编程模型,也有明显的确定,进程太重量,效率不高,创建、销毁、调度一个进程消耗时间比较多,为了解决该问题,就引入了 “线程(Thread)”,线程也叫作 “ 轻量级进程 ”。
线程与进程的关系:
线程的结构:每个线程也有状态,优先级,上下文,记账信息... ,可以独立的进行调度
上述结构决定了线程的特点:
总的来说:进程中包含线程 --> 一个进程由多个 PCB 共同表示 --> 每个 PCB 来表示一个线程 --> 每个线程都有自己的状态、上下文、优先级、记账信息 --> 每个线程都可以独立的去 CPU 上调度执行 --> 这些 PCB 共用了同样的内存指针 和 文件描述符表 --> 创建线程(PCB)不需要重新申请资源 --> 创建/销毁效率更高了。
问题:线程一定是越多越好吗?
🔥注:每个线程都是独立调度,在调度的时候,系统就不再考虑进程这样的概念了。
💞 💞 💞那么本篇到此就结束啦,如果我的这篇博客可以给你提供有益得参考和启示,可以三连支持一下!!!