React18原理: Fiber架构下的单线程CPU调度策略

概述

  • React 的 Fiber 架构, 它的整个设计思想就是去参考CPU的调度策略
  • CPU现在都是多核多进程的,重点研究的是
    • CPU是单核单线程,它是如何调度的?
    • 为什么要去研究单线程的CPU?
  • 浏览器中的JS它是单线程的
  • JS 的执行线程和浏览器的渲染GUI 是互斥的
  • 渲染和JS的执行都用同一个线程,因为一次只能做一件事情,所以互斥
  • 所以,React整个架构的整个调度都是去参考 CPU 的

单线程CPU调度策略


单处理器进程调度策略

  • 1 ) 先到先得(First-Come-First-Served,FCFS)

    • 可以把 CPU 理解为一个办事窗口, 比如说排队,有的人办的慢,有的人办的快
    • 比如,有人办事只需要一分钟,有的人却很墨迹,办事要半个小时
    • 办事墨迹的人,后面的人都一直在等着,所以这个先到先得的策略
    • 对于CPU来讲,其实就是不合理的,不能谁先来就先执行
    • 因为有的人比较着急(优先级高),放在后面不适合
    • 这是最简单的调度策略,简单说就是没有调度,谁先来谁就先执行
    • 执行完毕后就执行下一个,不过如果中间某些进程因为I/O阻塞了
    • 这些进程可能会重新排队了,需要留意的事:
    • FCFS对短进程不利
      • 短进程即执行时间非常短的进程
      • 可以用饭堂排队来比喻:
        • 在饭堂排队打饭的时候,一个人打包好几份
        • 这些人就像长进程一样,霸占着CPU资源
        • 后面排队只打一份的人会觉得很吃亏
        • 打一份的人会觉得它们优先级应该更高,毕竟它们花的时间很短
        • 反正你打包那么多份再等一会也是可以的,何必让后面那么多人等这么久…
    • FCFS对I/0密集不利
      • I/O密集型进程(这里特指同步I/O)在进行I/O操作时
      • 会阻塞休眠,这会导致进程重新被放入就绪队列,等待下一次
      • 可以类比银行部门办业务:假设CPU一个窗口、I/O一个窗口
      • 在CPU窗口好不容易排到你了,这时候发现一个不符合条件或者漏办了
      • 需要去 I/O 搞一下,要去I/O窗口排队,I/O执行完了
      • 到CPU窗口又得重新排队,这样,似乎也是不合理的
    • 所以FCFS这种原始的策略在单处理器进程调度中并不受欢迎

  • 2 )轮转调度

    • 轮转调度它是基于时钟的一种抢占策略
    • CPU的时钟其实就是根据它的这个帧幅周期
    • 这个就跟吃大锅饭一样,也没有体现一种权重
    • 最后, 比如说有人有急事,那这个时候搞轮转,也是不合适的
    • 它属于抢占策略中最简单的一种:
      • 公平地给每一个进程一定的执行时间,当时间消耗完毕或阻塞
      • 操作系统就会调度其他进程,将执行权抢占过来
    • 决策模式:
      • 抢占策略相对应的有非抢占策略
      • 非抢占策略指的是让进程运行直到结束、阻塞(如I/O或睡眠)
      • 或者主动让出控制权,抢占策略支持中断正在运行的进程
      • 将主动权掌握在操作系统这里,不过通常开销会比较大
    • 这种调度策略的要点是
      • 确定合适的时间片长度:太长了,长进程霸占太久资源
      • 其他进程会得不到响应(等待执行时间过长)
      • 这时候就跟上述的FCFS没什么区别了
      • 太短了也不好,因为进程抢占和切换都是需要成本的
      • 而且成本不低,时间片太短,时间可能都浪费在上下文切换上了
      • 导致进程干不了什么实事
    • 因此时间片的长度最好符合大部分进程完成一次典型交互所需的时间
    • 轮转策略非常容易理解,只不过确定时间片长度需要伤点脑筋
    • 另外和FCFS一样,轮转策略对I/O进程还是不公平

  • 3 )最短进程优先(Shortest Process Next,SPN)

    • 什么是短进程呢?
    • 短进程就跟排队一样,比如,我办事一分钟,我就是短进程
    • 你墨迹半个小时,你就是长进程
    • 所以,可以设计一种调度策略叫短进程优先
    • 如果说,我办的快,我就优先,那慢的一直在后面等着
    • 这样好像也有点不对劲,所以这个也有缺陷
    • 长进程就会饥饿,可能永远得不到响应,没法去执行, 所以,这个也不行
    • 上面说了先到先得策略对短进程不公平
    • 最短进程优先索性就让最短的进程优先执行
    • 也就是说:按照进程的预估执行时间对进程进行优先级排序
    • 先执行完短进程,后执行长进程,这是一种非抢占策略
    • 这样可以让短进程能得到较快的响应
    • 但怎么获取或者评估进程执行时间呢?
      • 一是让程序的提供者提供,这不太靠谱
      • 二是由操作系统来收集进程运行数据,并对它们进程统计分析
    • 例如最简单的是计算它们的平均运行时间
    • 不管怎么说都比上面两种策略要复杂一点
    • SPN的缺陷是:
      • 如果系统有大量的短进程,那么长进程可能会饥饿得不到响应
      • 另外因为它不是抢占性策略,尽管现在短进程可以得到更多的执行机会
      • 但是还是没有解决FCFS的问题:一旦长进程得到CPU资源
      • 得等它执行完,导致后面的进程得不到响应
  • 其他策略

    • 最短余(Shortest Remaining Time,SRT)
    • 最高响应比优先(HRRN)
    • 反馈法
    • 这里不再举例

前端框架解决上述问题的方向

  • 对于前端框架来说,解决这种问题有三个方向:
    • 1 )优化每个任务,让它有多快就多快。挤压CPU运算量
      • Vue 选择的是这一种,对于Vue来说,使用模板让它有了很多优化的空间
      • Vue使用依赖收集,基于Proxy来监听数据的变化,在get时收集依赖,在set时
      • 触发依赖渲染页面,配合响应式机制可以让Vue精确地进行节点更新
    • 2 )快速响应用户,让用户觉得够快,不能阻塞用户的交互(React分片)
      • React选择了这一种,一个任务,假如说要运行1秒钟
      • 那React通过分片之后,可能用了1.2秒,但是它却让你感觉很快
      • 实际上它的执行时间是没有降低的,但是它会让你感觉快
      • React 的 Reconcilatin 是 CPU 密集型的操作,它就相当于我们上面讲的
      • 长进程,所以初衷和进程调度一样,要让高优先级的进程或短进程优先运行
      • 不能让长进程长期霸占资源
    • 3 )尝试Worker多线程
      • 要保证状态和视图的一致性相当麻烦,这里不再赘述

React 不同模式的效果对比

1 )同步模式下的 React, 可以看到,阻塞比较严重

2 ) 异步 Concurrent 模式下的 React, 可以看到,非常流畅

React是怎么优化的

  • 为了给用户制造一种应用很快的假象,不能让一个程序长期霸占着资源
  • 可以将浏览器的渲染、布局、绘制、资源加载(例如HTML解析)、事件响应、脚本执行视作操作系统的进程
  • 需要通过某些调度策略合理地分配CPU资源,从而提高浏览器的用户响应速率,同时兼顾任务执行效率
  • 所以React通过Fiber架构,让 Reconcilation 过程变成可被中断
  • 适时地让出CPU执行权,让浏览器及时地响应用户的交互

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

倒计时61天

M-智乃的36倍数(normal version)_2024牛客寒假算法基础集训营3 (nowcoder.com) //非ac代码,超时了,54.17/100#include<bits/stdc.h> using namespace std; const int N1e55; const int inf0x3f3f3f3f; #define int long long int n; string s1[N]; void solve() {cin>…

STM32的ADC电压采集

时间记录&#xff1a;2024/2/9 一、ADC相关知识点 &#xff08;1&#xff09;STM32的ADC时钟不要超过14MHz&#xff0c;不然结果的准确率将下降 &#xff08;2&#xff09;ADC分为规则组和注入组&#xff0c;规则组相当于正常运行的程序&#xff0c;注入组相当于中断可以打断…

随机MM引流源码PHP开源版

引流源码最新随机MM开源版PHP源码&#xff0c;非常简洁好看的单页全解代码没任何加密 直接上传即可用无需数据库支持主机空间

RabbitMQ-4.MQ的可靠性

MQ的可靠性 4.MQ的可靠性4.1.数据持久化4.1.1.交换机持久化4.1.2.队列持久化4.1.3.消息持久化 4.2.LazyQueue4.2.1.控制台配置Lazy模式4.2.2.代码配置Lazy模式4.2.3.更新已有队列为lazy模式 4.MQ的可靠性 消息到达MQ以后&#xff0c;如果MQ不能及时保存&#xff0c;也会导致消…

如何使用websocket

如何使用websocket 之前看到过一个面试题&#xff1a;吃饭点餐的小程序里&#xff0c;同一桌的用户点餐菜单如何做到的实时同步&#xff1f; 答案就是&#xff1a;使用websocket使数据变动时服务端实时推送消息给其他用户。 最近在我们自己的项目中我也遇到了类似问题&#xf…

全功能的屏幕截图工具 - PicPick

全功能的屏幕截图工具 - PicPick 1. PicPick1.1. PicPick 中文1.2. Hot keys References 1. PicPick https://picpick.app/zh/ https://picpick.app/en/ A full-featured screen capture and recording tool, Intuitive image editor, color picker, color palette, pixel-ru…

re:从0开始的CSS学习之路 9. 盒子水平布局

0. 写在前面 过年也不能停止学习&#xff0c;一停下就难以为继&#xff0c;实属不应 1. 盒子的水平宽度 当一个盒子出现在另一个盒子的内容区时&#xff0c;该盒子的水平宽度“必须”等于父元素内容区的宽度 盒子水平宽度&#xff1a; margin-left border-left padding-lef…

使用Qt创建项目 Qt中输出内容到控制台 设置窗口大小和窗口标题 Qt查看说明文档

按windows键&#xff0c;找到Qt Creator &#xff0c;打开 一.创建带模板的项目 新建项目 设置项目路径QMainWindow是带工具栏的窗口。 QWidget是无工具栏的窗口。 QDuakig是对话框窗口。创建好的项目如下&#xff1a; #include "widget.h"// 构造函数&#xff…

Go内存优化与垃圾收集

Go提供了自动化的内存管理机制&#xff0c;但在某些情况下需要更精细的微调从而避免发生OOM错误。本文介绍了如何通过微调GOGC和GOMEMLIMIT在性能和内存效率之间取得平衡&#xff0c;并尽量避免OOM的产生。原文: Memory Optimization and Garbage Collector Management in Go 本…

回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制)

回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&…

在windows的控制台实现贪吃蛇小游戏

欢迎来到博主的文章 博主id&#xff1a;代码小豪 前言&#xff1a;看懂这篇文章需要具有C语言基础&#xff0c;还要对单链表具有一定的理解。如果你只是想要试玩这个游戏&#xff0c;可以直接在文章末尾找到源码 由于实现贪吃蛇需要调用Win32 API函数&#xff0c;这些函数我会…

JVM 性能调优 - Java 虚拟机内存体系(1)

Java 虚拟机我们简称为 JVM&#xff08;Java Virtual Machine&#xff09;。 Java 虚拟机在执行 Java 程序的过程中&#xff0c;会管理几个不同的数据区域。如下图所示&#xff1a; 下面我会介绍这几个数据区的特点。 堆 堆区的几个特点&#xff1a; 线程共享。启动时创建堆…

滑块识别验证

滑块识别 1. 获取图片 测试网站&#xff1a;https://www.geetest.com/adaptive-captcha-demo 2. 点击滑块拼图并开始验证 # 1.打开首页 driver.get(https://www.geetest.com/adaptive-captcha-demo)# 2.点击【滑动拼图验证】 tag WebDriverWait(driver, 30, 0.5).until(la…

Spring Boot 整合 Redis 使用教程

作为开发者&#xff0c;相信大家都知道 Redis 的重要性。Redis 是使用 C 语言开发的一个高性能键值对数据库&#xff0c;是互联网技术领域使用最为广泛的存储中间件&#xff0c;它是「Remote Dictionary Service」的首字母缩写&#xff0c;也就是「远程字典服务」。 Redis 以超…

Mac电脑清空特别大型旧文件如何一键清理?

在我们的数字生活中&#xff0c;Mac电脑常常承载着大量个人资料和重要文件。但当我们决定把自己的Mac送给亲人或朋友使用时&#xff0c;面临的首要任务便是彻底且高效地清空所有个人数据&#xff0c;以保证隐私安全。传统的删除方法虽然简单&#xff0c;但往往不能彻底清除所有…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先&#xff0c;WebSocket和HTTP是两种不同的协议&#xff0c;它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别&#xff1a; HTTP (HyperText Transfer Protocol): 请求-响应模型&#xff1a; HTTP 是基于请求-响应模型的协…

VXLAN:虚拟化网络的强大引擎

1.什么是VXLAN VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;&#xff0c;是由IETF定义的NVO3&#xff08;Network Virtualization over Layer 3&#xff09;标准技术之一&#xff0c;是对传统VLAN协议的一种扩展。VXLAN的特…

嵌入式系统:挑战与机遇并存的领域

嵌入式系统&#xff1a;挑战与机遇并存的领域嵌入式系统是一个既具有挑战性又充满前景的领域。要成为一名合格的嵌入式系统工程师&#xff0c;需要经过大量的学习和实践。然而&#xff0c;进入这个领域时&#xff0c;刚入行可能会面临许多困境。让我们一起探讨一下嵌入式系统工…

JAVA反射总结学习

初始反射反射的基本操作反射安全性问题 反射是指在Java运行状态中: 给定一个类对象(Class对象)&#xff0c;通过反射获取这个类对象(Class对象)的所有成员结构&#xff1b; 给定一个具体的对象&#xff0c;能够动态地调用它的方法及对任意属性值进行获取和赋值&#xff1b; …

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测 目录 多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预…