linux操作系统和系统资源理论基础

2023-05-16


目录

一:操作系统

二:程序如何被CPU读取

三:CPU缓存

四:CPU缓存策略

五:如何实现系统多任务

六:进程切换过程初探

七:进程的调度规则

八:CPU指令集


 

一:操作系统

        操作系统本质也是一组程序,它是一组接口程序,其作用是提供给用户与计算机交互的接口,不管是windows的图形化桌面,还是linux系统的shell命令行,都是一组用来提供给人类与计算机硬件交互的接口程序而已

内核是什么?

 内核是操作系统的核心,也是操作系统最重要的组成部分,用于管理计算机所有活动并驱动所有硬件。明确来说内核管理操作系统的进程,内存,网络功能,文件系统,硬件的驱动程序等等,因为人类直接操作硬件想要利用硬件资源完成计算的任务是很复杂的,因而内核隐藏了这些复杂性,提供了统一的简洁的接口使得程序开发设计更为简单

而计算机的价值是计算功能,被计算的对象就是为了实现某些功能而编写的代码。在系统上运行的服务是由开发人员编写的代码程序来实现,程序在系统中运行需要解决很多问题,了解了这些问题以及如何解决这些问题,对于进程如何运行以及系统资源的调度就有了一定的理解

 

二:程序如何被CPU读取

   程序是实现某种功能的代码集合体,而运行程序所需的计算能力由CPU提供,因此程序必须要放入CPU中运行。而程序本质也只是由程序员编写的静态的文件,因此它与其它文件一样是保存在硬盘中的。但是CPU的运算速率极高,与磁盘较低的读写速率相差极大,因此无法直接与磁盘进行数据交互。

  因而需要速率更快的中间件作为两者的桥梁,这就是内存,虽然内存的读写速率要比磁盘高很多,但和CPU的运算速率相比还是慢很多,为了能一定程度上弥补两者速率上的差距,CPU引入了缓存机制。

三:CPU缓存

  CPU缓存一般有三级缓存,一级缓存速率近乎接近于CPU速率,成本最高空间小,因此需要有稍大些空间的二级缓存来提供使用,而一级缓存可用来弥补二级缓存与CPU速率上的差距,同理二级缓存用来弥补三级缓存和一级缓存速率的差距,而三级缓存是CPU共享的空间容量也较大,一二级缓存属于CPU独有的,如果CPU是多核的那每颗核心都有自己的一二级缓存。因此在购买PC机时性能体系不止是CPU内存等常规硬件数据,CPU缓存大小也极大影响着计算机性能,通常一级缓存容量多出一倍的计算机通常价格也会高出很多

  一级缓存是CPU处理数据的直接接口,CPU访问到的数据一定是来自一级缓存的,而使用N路关联技术能保障缓存RAM中数据的命中率,同时保障了缓存不会被置换的过于频繁,从此CPU只通过一级缓存读取数据,如果一级缓存中没有数据,就从二级缓存中置换到一级缓存,如果二级缓存也没有,那就从三级缓存中置换,如果三级缓存中没有,就从内存中缓存,这样逐级置换。而读取到缓存中的数据同时会把数据的数据块调入缓存里,此后读取数据直接从缓存里取。大大减少了CPU与R内存直接数据交互概率。而内存其实在本质也属于CPU缓存一种表现形式,只不过它是用来实现CPU与硬盘速率差距的中间层,并且它在速率上仍然不足以弥补差距,因此又需要CPU的三级缓存来弥补

四:CPU缓存策略

  CPU与它的三级缓存也是需要通过一定策略机制来保障CPU读取数据和数据同步的。

有两种:1.回写策略2.通写策略

设想一下:如果当CPU更新了一级缓存中数据,那么需要随即跟新到二级缓存吗,需要随即更新到三级缓存吗?需要随即跟新到内存吗?

  如果不逐级更新的话会如何呢?首先不逐级更新的话系统就无法把CPU更新的数据通过缓存逐级置换保存到内存中,那么就无法通过内存把数据刷新到磁盘中,此时如果断电了,而CPU是没有保存数据场所的,数据将会丢失,因此当CPU更新了一级缓存时同时需要逐级更新至内存中的,这种策略叫做通写策略

  但如果每当缓存中有数据更新后都更新到内存中的话也会导致性能降低的。因此还有一种性能更高的CPU缓存策略叫回写策略:当CPU更新一级缓存数据后,不会立即更新至内存,只有当该数据要从一级缓存中丢弃时才逐级更新至内存中。很显然回写策略比通写策略性能要高,因此现在CPU使用的缓存策略都是回写策略

五:如何实现系统多任务

  程序需要运行,首先得由内存把程序文件从磁盘中读取后,通过三层缓存至CPU中运行。现在操作系统是多任务的,即众多进程可以同时运行。但其实CPU某一时刻只能运行一个进程,但系统上都有大量的进程需要运行,例如单核的CPU同一时间其实只能处理一个进程,如果CPU是八核心的那某一时刻能运行八个进程任务,而系统中进程的数量是远超CPU核心数的,更何况还有很多后台守护进程。但为什么我们日常使用电脑都可以同时运行很多软件呢,看起来就是多任务的呀?因为多任务的实现方式是把CPU的运算能力以时间为单位来进行切割,分给每个进程一个运行时间片,这样CPU在众多的进程中来回切换运行,每个进程只有短暂的毫秒运行时间,时间到了即切换到下一个进程,由于速度极快,因此在我们看来好像是CPU同时运行多个进程的。

六:进程切换过程初探

  那么CPU在如此众多的进程之间切换进行运行肯定是某些机制来保障稳定无差错的,下面来看下具体是如何实现的:

首先1:当一个进程在CPU的某颗核心上运行的时间结束后需要退场,但是这个进程中的指令仍然没有运行结束,还有指令需要继续执行。那就意味着还需要再次调度到CPU上运行,那么该进程下次运行是从哪条指令开始运行呢?

总不能上次运行了一半指令,下次调度到CPU上又得从头开始运行吧?这显示是不合理的。因此需要有一种机制来记录进程的在CPU上的运行状态。

其次2:进程等待下次调度到CPU核心上继续运行,但系统上那么多进程呢?那么是通过何种机制来保障它就一定可以被调度到CPU上运行呢?并且何时被调度到CPU上继续运行呢?

  就以上两个问题我们进一步了解进程的调度过程。首先进程是在CPU上运行的,但进程的管理和调度工作是由内核实现的,为了保证每个进程退场后下次入场能继续沿着上次执行指令的位置继续往下运行,因此在CPU运行过程中CPU需要记录进程的指令执行位置的状态信息,完成此项工作的是CPU的指令指针寄存器,它永远指向下一条指令(比如进程上次执行到了第50条指令时就退出CPU了,下次调度到CPU上必须是从第51条指令继续执行的),而每一次进程被调度到CPU上运行,CPU寄存器就会记录该进程的执行状态信息,那么势必会刷新前面的进程记录在寄存器中的信息的,那么记录的数据就会丢失了。并且CPU是没有存放数据的空间场所的,寄存器只是个临时记录信息的场所。因而当进程退出CPU时就需要把自己的运行位置信息找一个可永久存储的地方,所以内核需要有个永久存储该信息的地方。而这个场所就是内核的内核空间,当进程退出时寄存器就把该状态信息保存到了内核中(这叫做保存现场)。具体位置在内核空间中对应的这个进程的进程描述符结构信息中(内核为了便于管理如此多的进程,在每个进程被创建的时候就会为它们创建一个进程描述符来保持进程的相关信息,下面会具体谈到进程描述符)。

那我们想以一下,当下一个被调度到CPU上运行的进程,它有没有可能是之前已经在CPU上运行过的呢?如果有那么它肯定在寄存器中保留了上次运行的状态信息的,那么是不是需要将进程保存的现场信息进行恢复呢,好让进程能接着上次的进度接着运行。这就是恢复现场的动作,进而保障它继续正常运行。因而进程之间的切换势必会不断的发生保存和恢复现场的动作(这个动作其实远远不止是进程状态位置这一个参数的保存和恢复,后面会详细铺开讲解)。而这个切换也是需要时间的,也会造成CPU资源浪费在进程切换上。事实上内核为了实现进程管理,且为了要能追踪到每个进程的执行状态信息,要明确知道当前系统启动了多少进程,另外需要记录的信息很多:(每个进程执行次序,执行时间,退场时执行位置...)而为了快速且有条理的完成这些工作,每创建一个进程时,内核在内核空间中都会为每个进程创建一个进程描述符(stak structure),这个进程描述符是内核存放进程信息的固定数据结构格式,用来描述进程状态信息的。因此每个进程在内核的内核空间中都有属于自己的数据结构,记录着每个进程的进程名,在内存中占用的页面,运行状态信息等等。有了这些信息内核管理进程变的得心应手。而内核的内核空间是在内存中的,内存空间总体上分为用户空间和内核空间

七:进程的调度规则

    而系统上众多的进程需要被运行,可提供资源的CPU核心数量是有限的,因此也跟我们人类社会一样需要有一定的规则次序来保障有限的公共资源被每个进程相对公平的使用,首先不能让进程乱做一团,得让进程按照一定的规则等待CPU资源。得所有的进程在一个有组织的队列中,每个CPU核心都有一个进程队列,比如8核心的CPU那就有八个这样的队列,所以同一时刻可以允许八个进程同时运行。人类排队一般就是按照队列顺序来进行划分优先级的,而进程调度并不是依靠排队的先后顺序的,那CPU是如何来判断这些进程执行的先后顺序的呢?因此需要有个界定进程的标签来让进程选择。而这个标签就是进程的优先级。优先级分为三类:1.实时优先级2.静态优先级,3.动态优先级

实时优先级的进程一般是跟内核相关的或者重要的进程,需要优先被运行的。因此实时优先级全部高于静态优先级。用数字1-99来表示,数字越大优先级别越高

静态优先级用数字100-139来表示,数字越小优先级越高

而内核在实现进程调度时对这两种不同优先级的调度方式也是不同的。不同优先级会有不同的进程调度器来完成调度策略。

如下几种调度策略:

SCHED_FIFO: 最简单的调度算法,先进先出队列:谁先到谁先运行

SHCED_RR: 轮调,同级别优先级的进程按照时间片进程

SCHED_Other:用来调度用户空间进程的100-139之间的进程

CFS SCHED:完全公平调度器 调度用户空间静态优先级

使用如下命令可查看进程的调度类别:

下图FF就是SCHED_FIFO调度器

TS就是SCHED_Other调度器,因此TS用来调度100-139优先级的进程的

 上图可以看见有些内核线程的优先级是实时的虽然它有PRI值,但是没意义,两个内核线程的实时优先级是99,是最高级别的,因为这两个内核线程极为重要的,而其它很多内核线程也都是以用户空间优先级方式来定义的

class:调度类别

rtprio:实时优先级

pri:进程的优先级

nice:调整静态优先级

而如果有些进程优先级很低排在它前面的进程一直存在那么这个低优先级进程就得不到运行。而为了保障社会的公平性,不会有人被饿死,内核引用了动态优先级来调整,并监控这些优先级,如果某些进程很久都没有被调度到CPU上运行了,内核会在内部临时性的调高进程的优先级,这就叫做动态优先级。根据进程优先级可知一般可能需要被内核动态调整的进程应该是100-139的静态优先级的进程

而为了让用户按需调整进程优先级,给每个进程都分配了nice值,可以通过管理员用户来调整进程的nice值从而调整进程的优先级,nice值与优先级的对应关系如下

nice值:100-139  对应进程的静态优先级: -20-19

而普通用户只能调低进程优先级, 管理员用户可以调低或调高自己的优先级

   再进一步分析:虽然进程优先级可以保障进程有次序的被调度,但是在队列里众多的进程中挑选出下面哪一个进程调度到CPU中也是很复杂的算法。如果内核遍历扫描进程未免效率过低了,并且有很多相同优先级的进程。为了实现快速的调度功能,内核将每个队列按照优先级再次进行内部划分(跟以前学校划分阳光班一样按成绩划分不同等级的班级体),内核将按照进程的139个优先级分为139个队列,每一个优先级别的进程为一个队列,下面只需要扫描每个队列的首部,就知道这个队列里的进程是哪个优先级别的了,按照队列的优先级从高到低,只要优先级高的队列中是有进程的,那就挑选出来调度到CPU上,直到队列扫描为空后再进行次级别的级队列进行扫描。

八:CPU指令集

 了解了内核管理进程的一些原理后,进一步深入具体管理方式,但在这之前先了解下CPU指令

一:CPU指令集分为特权指令和普通指令

   1.特权指令:指的是需要调用硬件资源完成某些工作,是不允许程序自己调用,比如一条mkdir指令创建一个文件。这就需要在硬盘上存数据,涉及到硬件资源调度了,而计算机的所有硬件是统一由内核来管理的。因此这种指令是无法直接由CPU执行完成的。并且任何需要用到特权指令的的功能,都由操作系统把它封装成了一个一个的调用,任何程序不能直接操作,必须先向内核申请系统调用才行,申请调用后由内核来接管进行操作,由用户模式进入内核模式

   2.普通指令:即不需要调用硬件资源,由CPU即可在用户空间中完成

我们把执行用户代码的机制叫做用户空间也叫用户模式,表示整个操作系统运行在用户模式下,而一旦用户模式中的指令发起系统调用,意味着不在执行用户代码,是在执行内核代码,而把执行内核代码的机制叫做内核空间也叫内核模式

由上可见,一个程序中的指令一般都会包含特权指令和普通指令,这也意味着进程执行过程中需要向内核申请调用,因此进程运行过程中往往都是在用户模式和内核模式下来回切换的,而这种切换本身也需要时间消耗资源的。因此如果一个程序在运行过程中大量时间都花费在了内核模式下,显示是不理想的,有生产能力的程序应该大部分时间都在执行用户代码上。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux操作系统和系统资源理论基础 的相关文章

  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b
  • 如何成功使用RDAP协议代替whois

    我对新的 RDAP 协议有点困惑 也不知道何时进一步追求它有意义 在我看来 每个人都同意它是 whois 的继承者 但他们的数据库似乎是空的 在 ubuntu 上我尝试了 rdapper nicinfo 甚至他们的 RESTful API
  • 操作系统什么时候清除进程的内存

    进程在某些操作系统上成功或异常终止 操作系统何时决定擦除分配给该进程的内存 数据 代码等 在退出时或当它想为新进程分配内存时 这个清除内存分配过程在所有操作系统 winXP Win7 linux Mac 上都相同吗 据我了解 页表具有该进程
  • InstaPy:“错误,无法确定 64 位 Linux 的正确文件名”

    有人知道如何解决或解决这个问题吗 来自控制台的堆栈跟踪 执行后报告错误 InstaPy Version 0 6 9 Workspace in use home zanettra InstaPy Error unable to determi
  • 停止服务时单元陷入故障状态(状态=143)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的问题 我有 CentOS 和 java 进程在上面运行 Java进程是通过启动 停止脚本来操作的 它也创建了 java 实例的 p
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 无需 cron 在后台发送邮件

    我想知道是否有一种方法可以运行 PHP 循环 以便在后台向订阅者发送几百封电子邮件 我的目标是格式化新闻通讯 单击发送 然后关闭浏览器或更改页面 当然 发送电子邮件的实际过程将在后台运行 不会因浏览器关闭而中断 我知道这可以通过 cron
  • arm-linux-gnueabi 编译器选项

    我在用 ARM Linux gnueabi gcc在 Linux 中为 ARM 处理器编译 C 程序 但是 我不确定它编译的默认 ARM 模式是什么 例如 对于 C 代码 test c unsigned int main return 0x
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • bluetoothctl 到 hcitool 等效命令

    在 Linux 中 我曾经使用 hidd connect mmac 来连接 BT 设备 但自 Bluez5 以来 这种情况已经消失了 我可以使用 bluetoothctl 手动建立连接 但我需要从我的应用程序使用这些命令 并且使用 blue
  • 为什么我收到“无法进行二进制日志记录”的信息。在我的 MySQL 服务器上?

    当我今天启动 MySQL 服务器并尝试使用以下命令进行一些更改时用于 MySQL 的 Toad http www quest com toad for mysql 我收到此消息 MySQL 数据库错误 无法进行二进制日志记录 消息 交易级别
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案

随机推荐

  • LeetCode739:每日温度

    要求 给定一个整数数组 temperatures xff0c 表示每天的温度 xff0c 返回一个数组 answer xff0c 其中 answer i 是指对于第 i 天 xff0c 下一个更高温度出现在几天后 如果气温在这之后都不会升高
  • 八大排序算法

    介绍 排序也称排序算法 Sort Algorithm xff0c 排序是将一组数据 xff0c 依指定的顺序进行排列的过程 排序分类 1 内部排序 指将需要处理的所有数据都加载到内部存储器 内存 中进行排序 2 外部排序法 数据量过大 xf
  • 时间复杂度和空间复杂度详解及排序算法复杂度

    时间复杂度 度量一个程序 算法 执行时间的两种方法 1 事前估算法 通过分析某个算法的时间复杂度来判断哪个算法更优 2 事后统计法 这种方法可行 xff0c 但是有两个问题 xff1a 一是要想对设计的算法的运行性能进行评测 xff0c 需
  • Java反编译工具JAD的安装与简单使用

    jad介绍 jad 是一个使用非常广泛的 Java 反编译工具 可以将java编译后的class文件反编译成对应的java文件 下载地址 JAD下载地址 xff0c 点击跳转https varaneckas com jad 按照自己的需求
  • python Counter() 函数

    目录 1 以统计列表中的词频为例 2 寻找出现次数最多的 k 个数 刷 leetcode 时发现了可以很方便地统计词频的 Counter 函数 xff0c 有了这个函数就不用手动的使用 for 循环来手动统计词频啦 xff01 Counte
  • C++11 新特性简介

    1 auto auto是旧关键字 xff0c 在C 43 43 11之前 xff0c auto用来声明自动变量 xff0c 表明变量存储在栈 xff0c 很少使用 在C 43 43 11中被赋予了新的含义和作用 xff0c 用于类型推断 a
  • Java反射(Reflex)机制

    反射概述 Reflection 反射 是Java被视为动态语言的关键 xff0c 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息 xff0c 并能直接操作任意对象的内部属性及方法 加载完类之后 xff0c 在
  • 偏航角、俯仰角、滚动角

    偏航角 俯仰角 滚动角 在姿态估计中 xff0c 常常会提到三个概念 xff0c 就是偏航角 俯仰角和滚动角 姿态估计是物体在三维空间内方向的表征 通常描述物体姿态以大地作为参考系 xff08 标准坐标系 xff09 将世界坐标系 xff0
  • 定时器与计数器的区别

    曾经我在北方工业大学复试的时候 xff0c 有个老师问了我个问题 他说同学你好 xff0c 我看你前面一直都在说深度学习的问题 xff0c 请问你对单片机了解吗 xff1f xff0c 请问定时器与计数器的区别是什么 xff1f 我告诉他
  • 编译make px4_fmu-v2_default upload时,报错ERROR Board can accept larger flash images (2080768 bytes)

    编译make px4 fmu v2 default upload时 xff0c 报错ERROR Board can accept larger flash images 2080768 bytes than board config 103
  • vue中实现axios封装

    vue中实现axios封装 为什么要进行axios封装vue项目安装axios封装前的get和post请求封装后的get和post请求 为什么要进行axios封装 实际开发过程中可能有几种环境 xff0c 开发环境 xff0c 测试环境 x
  • 项目实训—场景划分(一)

    1 什么是场景 xff08 Scene xff09 场景作为电影讲故事的关键单元 xff0c 包含了演员的复杂活动及其在物理位置上的互动 识别场景的组成和语义是视觉理解复杂长视频 xff08 如电影 电视剧 娱乐节目和综艺节目 xff09
  • 手把手教你FreeRTOS源码解析(一)——内存管理

    FreeRTOS中一共有5种内存分配的方法 xff0c 分别在文件heap 1 c heap 2 c heap 3 c heap 4 c heap 5 c种 虽然标准C库中的 malloc 和 free 也可以实现动态内存管理 xff0c
  • 手把手教你FreeRTOS源码详解(二)——任务管理

    FreeRTOS源码解析集合 xff08 全网最详细 xff09 手把手教你FreeRTOS源码解析 xff08 一 xff09 内存管理 手把手教你FreeRTOS源码详解 xff08 二 xff09 任务管理 手把手教你FreeRTOS
  • 手把手教你FreeRTOS源码详解(三)——队列

    FreeRTOS源码解析集合 xff08 全网最详细 xff09 手把手教你FreeRTOS源码解析 xff08 一 xff09 内存管理 手把手教你FreeRTOS源码详解 xff08 二 xff09 任务管理 手把手教你FreeRTOS
  • 手把手教你FreeRTOS源码详解(四)——信号量、互斥量、递归互斥量

    FreeRTOS源码解析集合 xff08 全网最详细 xff09 手把手教你FreeRTOS源码解析 xff08 一 xff09 内存管理 手把手教你FreeRTOS源码详解 xff08 二 xff09 任务管理 手把手教你FreeRTOS
  • python 随机数 random 库的使用总结

    目录 1 random 库中的常用随机数生成函数 2 一些用法举例 3 随机数种子 seed a 的理解与使用 random 库的主要目的就是生成随机数 1 random 库中的常用随机数生成函数 from random import 1
  • JDBC 配置

    JDBC Java DataBase Connectivity 规范 JDBC是一套协议 xff08 规范 xff09 是java开发人员和数据库厂商达成的协议 是由sun定义一组接口 由数据库厂商来实现 并规定了java开发人员访问数据库
  • Gazebo下载所有模块到本地

    从https bitbucket org osrf gazebo models上下载model库 xff1b 将下载的文件解压 xff0c 将解压后的文件夹重命名为models将models复制到 gazebo文件夹中 xff08 如果 g
  • linux操作系统和系统资源理论基础

    目录 一 xff1a 操作系统 二 xff1a 程序如何被CPU读取 三 xff1a CPU缓存 四 xff1a CPU缓存策略 五 xff1a 如何实现系统多任务 六 xff1a 进程切换过程初探 七 xff1a 进程的调度规则 八 xf