先撸清楚:并发/并行、单线程/多线程、同步/异步

news2025/1/12 15:47:51

前言

在编码的过程中经常会遇到并发/并行、同步/异步、单线程/多线程等术语,在分析JS setTimeout/Promise之前先把这些概念厘清。
通过本篇文章,你将了解:

  1. 并发/并行的概念及区别
  2. 同步/异步的概念及区别
  3. 单线程/多线程的概念及区别
  4. 主线程和子线程的概念及区别
  5. JS执行引擎是单线程吗?

1. 并发/并行的概念及区别

1.1 并发

1.1.1 无并发时代

在远古时代(其实就是几十年前),计算机硬件基础比较落后,刚开始只有一个CPU核心。
计算机操作员需要把待完成的事项编排为一个个的任务,依次交给CPU去执行。
image.png
可以看出,任务是依次执行的,上一个任务未执行完(未释放CPU),下个任务是不能执行(获取CPU)的。

1.1.2 单核并发

假设任务3执行时间需要4s,任务4执行时间需要6s,执行完任务3和任务4总共需要10s的时间。
任务3执行的过程中需要等待读取磁盘(磁盘读取需要2s),此时任务3是不怎么占用CPU的,它完全可以先释放CPU专注等待磁盘读取,而此刻任务4就可以有机会得到CPU的执行,任务3磁盘读取返回后继续申请CPU执行未完成的项。
此时任务3、4执行完成总共需要2+6=8s时间。
任务间的执行流程大致如下:
image.png
在一段时间内,任务3和任务4是共存的(任务3执行的过程中,任务4可以插进来),同样的,任务3、任务4执行的过程中也可以插入其它任务5、6…n,此种设计方式可以在一定程度上提高CPU的利用率。
因此,我们简单归纳一下:

  1. 若一个系统支持同时存在多个任务(任务交替运行),则称该系统支持并发
  2. 在单核心的CPU场景下,同一时间只会有一个任务得到执行,CPU将时间分给多个任务执行,CPU执行任务的速度非常快,给人的感觉是多个任务是同时处理完毕的,实际上是分享了CPU的时间片

1.1.3 多核并发

随着硬件的发展,CPU从单核变成多核,每个核心都能独立处理各自的任务,此种场景下,并发的功能依然存在,如下图:
image.png
很容易理解,单核心能够并发,多核心更不在话下了。

1.2 并行

从多核并发的图里,我们知道CPU1的任务队列和CPU2的任务队列可以同时进行。
image.png
如图,同一时刻,任务3在CPU1里执行,任务8在CPU2里执行,通过增加CPU核心数,处理任务的速度更快了。
因此,我们简单归纳如下:

  1. 若一个系统支持同时运行多个任务,则称该系统支持并行。
  2. 并行从字面上意思就是两人在一起肩并肩并排行走。

2. 同步/异步的概念及区别

2.1 量血压的例子

先看一种场景:
小明去医院体检,他决定量血压,此时量血压的人都排成一队了,他排在了队伍的末尾。
如果把医生当做线程,队伍里的每个人都是一个代码行(方法/函数),每个人都按序等待量血压(代码行等待线程执行),前一个人量好了再到下一个人。
我们称这些代码行是按时间先后顺序同步地执行。
image.png

再看另一种场景:
小明去医院体检,他起得比较晚,急匆匆跑到医院的时候,他决定先量血压。此时量血压的人都排成一队了,他排在了队伍的末尾。
轮到他测量血压的时候,医生发现他心跳比较快,于是建议他先休息冷静一会儿再来测,于是他坐到了一旁冷静平复心情。
当他休息的差不多的时候,他又去排队,最终他量好了血压。

image.png

小明确实是排了队,医生那会儿没给他量血压,告诉他满足条件后再来,当满足条件后再重新排队。
我们称此时小明量血压的过程是异步地执行。

2.2 转为TS代码

同步:

//ts 代码
function testBPSync(name:String) {
    console.log(name, 'test bp')
}

testBPSync('体检者1')
testBPSync('体检者2')
testBPSync('小明')
testBPSync('体检者3')

image.png

可以看到打印是依次执行的。

异步:

//ts 代码
function testBPSync(name:String) {
    console.log(name, 'test bp')
}

function testBPAsync(name:String) {
    setTimeout(()=>{
        console.log(name, 'test bp')
    }, 2000)
}

testBPSync('体检者1')
testBPSync('体检者2')
testBPAsync('小明')
testBPSync('体检者3')

image.png
可以看到,虽然小明排在体检者3之前,但是他并没有在体检者3前被量血压,它是过一会才被量,是异步执行的。

2.3 异步==另一个线程?

小明量血压是异步的,但他最终还是同一个医生给他量的,我们把医生比作执行在CPU上的线程,此时虽然是异步的,但并不等于在另一个线程里执行。
上图使用的setTimeout()最终回调还是在主线程里执行。

小明平复了心情后,另一个体检医生让他过去体检,此时他就不在原来的医生那体检了,此种场景对应在另一个线程里执行:

//Kotlin 代码
fun testBPsync(name:String) {
    println("${name} test bp")
}

fun testBPAsync(name:String) {
    thread {
        //在另一个线程里执行
        println("${name} test bp")
    }
}

fun main() {
    testBPSync('体检者1')
    testBPSync('体检者2')
    testBPAsync('小明')
    testBPSync('体检者3')
}

总结来说:

  1. 同步:表示在一个线程里按照时间的先后顺序执行代码
  2. 异步:同步反义词,异步执行的代码可能在同一个线程执行,也可能在另一个线程执行,取决于具体的实现逻辑,异步通常表现为回调的形式。

3. 单线程/多线程的概念及区别

在最开始我们有提到过任务的并发执行,先执行任务的一部分,再执行其余部分,这种"部分"在CPU上是如何调度的呢?
答案是线程。
先了解一个老生常谈的知识:

进程是资源分配的基本单位,线程是CPU任务调度和执行的基本单位

image.png
CPU上执行的是线程,不同进程(任务)的线程、同一进程里的线程交替在CPU上执行,达到了并发的效果。

多线程能够充分利用CPU的能力,比如某个进程里开了两个线程分别去获取网络数据和进行磁盘I/O读写,这俩线程可以同时执行(并行),也可以并发,提升了效率。

但多线程也带来了挑战:

  1. 线程之间的互斥,多线程修改同一内存变量的一致性,通常加锁解决
  2. 线程之间的同步,某个线程修改同一内存变量后通知其它线程变量已经修改,通常等待-通知机制解决

因此多线程编程永恒的话题:线程间的同步和互斥

单线程永远不会担心同步和互斥,单线程通常伴随着事件循环。

有关线程和锁相关请移步系列文章:线程和锁系列

4. 主线程和子线程的概念及区别

承担着进程入口的线程,通常称为主线程。
一般来说我们编写Hello World会有个Main入口,执行此处代码的就是主线程。

image.png

实际上主线程和子线程本质上是没有区别的,都是通过构造线程对象并执行代码。
在Android、iOS设计里,把一个线程选作主线程,那么就会在更新UI的时候做一些校验,判断是否是主线程(UI线程),如果不是那么不允许操作界面元素。并且主线程主要做一些UI布局计算相关的操作(不是渲染线程),同时响应其它线程的事件,比如触摸事件等,因此它一定要比较流畅,不能被同步阻塞,轻则界面卡顿,重则App Crash,因此阻塞的事情交给其它线程(子线程)去做。

5. JS执行引擎是单线程吗?

答案是的。
至于为什么选择单线程,前面也有提到一些。

  1. 单线程不用考虑多线程里的同步互斥问题,无需上锁,无需来回切换线程,简单纯粹
  2. 主线程通常用来更新UI元素,保证唯一的修改源可以减少很多莫名其妙的问题

了解了以上概念,将助力我们进入下篇的Promise/SetTimeout的世界。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Next App Router(中)

1.定义布局 布局是指多个页面共享的 UI。在导航的时候,布局会保留状态、保持可交互性并且不会重新渲染,比如用来实现后台管理系统的侧边导航栏。 定义一个布局,你需要新建一个名为 layout.js的文件,该文件默认导出一个 React 组…

XUbuntu18.04 源码编译Qt4.5.3的过程

由于新公司很多旧的软件都是基于这个版本做的嵌入式开发。 所以想要自己搭一套基于Linux的非嵌入式开发环境,方便用来调试和编译代码。 这样就可以完成在linux下开发,然后直接嵌入式打包,涉及到界面的部分就不需要上机调试看问题了。 所以…

一个完全用rust写的开源操作系统-Starry

1. Starry Starry是2023年全国大学生计算机系统能力大赛操作系统设计赛-内核实现赛的二等奖作品。Starry是在组件化OS的arceos的基础上,进行二次开发的操作系统内核,使用宏内核架构,能够运行Linux应用的内核。 原始的操作系统大赛的仓库为 …

linux 基础命令docker及防火墙iptables详解

应用场景: web应用自动打包和发布 自动化测试,持续集成、发布 在服务环境中部署后台应用 搭建paaS平台 安装应用 apt install docker.io#kali中 配置docker源,文件位置/etc/docker/daemon.json { "registry-mirrors": [ "h…

原牛角源码(修罗bbs)全站程序打包带数据库备份

原牛角源码(修罗bbs)全站程序打包带数据库备份,牛角源码全站数据全站文件、插件打包分享给大家,有兴趣的可以搭建玩玩! conf文件夹中自己配置conf.php里面的数据库链接文件,默认管理账号:admin,密码&#…

【大数据】bigtable,分布式数据库的鼻祖

目录 1.概述 2.数据模型 3.API 4.架构 5.一个完整的读写过程 6.如何查找到要的tablet 7.LSM树 1.概述 本文是作者阅读完bigtable论文后对bigtable进行的一个梳理,只涉及核心概念不涉及具体实操,具体实操会在后续的文章中推出。 GFS的出现虽然解…

上位机图像处理和嵌入式模块部署(树莓派4b实现xmlrpc通信)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面,我们也用纯API实现过上位机和开发板之间的通信。当时使用的方法,就是用windows自带的网络sdk和linux自带的api函数来完…

分享4张亚马逊云科技AWS免费云开发和AI证书(有答案)

今天给大家带来特别福利,一口气带来亚马逊云科技AWS4张免费云开发/AI证书(有Credly徽章,有答案),这四门都是云开发相关的硬核知识,含金量极高。 主要考察如何用AWS AI服务进行开发、以及当下热门的云原生改造,16道题80…

葡萄书--关系图卷积神经网络

异质图和知识图谱 同质图与异质图 同质图指的是图中的节点类型和关系类型都仅有一种 异质图是指图中的节点类型或关系类型多于一种 知识图谱 知识图谱包含实体和实体之间的关系&#xff0c;并以三元组的形式存储&#xff08;<头实体, 关系, 尾实体>&#xff0c;即异…

IP地址定位:揭秘精准定位的技术与应用

在数字化时代&#xff0c;IP地址已成为连接互联网世界的关键标识之一。但是&#xff0c;很多人对于IP地址的精准定位能力存在疑虑。本文将深入探讨IP地址定位的技术原理以及其在实际应用中的精确度。 IP地址查询&#xff1a;IP数据云 - 免费IP地址查询 - 全球IP地址定位平台 …

Python中的设计模式与最佳实践

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python中的设计模式与最佳实践 在软件开发中&#xff0c;设计模式是一种解决常见问题的经过…

怎么把网页上的文字变小?

以下是针对常见浏览器的说明&#xff1a; ### Google Chrome&#xff1a; 1. 打开 Chrome 浏览器并导航到您想要调整文字大小的网页。 2. 在页面上右键单击空白处&#xff0c;然后选择 "检查" 或按下 CtrlShiftI&#xff08;在 Windows 或 Linux 上&#xff09;或 Co…

【剪映专业版】14为视频添加炫酷特效

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 1.特效 画面特效&#xff1a;用于整个画面 人物特效&#xff1a;仅用于画面中的人物&#xff0c;如画面中无人&#xff0c;则不起作用 2.添加特效 按号添加 可通过鼠标推动实现特效时间调节 可叠加使用特效 3.特效修…

关于ERA5气压和温度垂直补偿公式的对比情况

1. 气压和温度垂直补偿对比 「谨代表给个人观点&#xff0c;杠精请自测&#xff0c;对对对&#xff0c;好好好&#xff0c;你说啥都对」。 使用2020-2022陆态网GNSS与探空站并址的48个站点实验&#xff0c;以探空站为真值&#xff0c;验证ERA5精度。怎么确定并址请看前面文章…

平衡二叉树(后序遍历,力扣110)

解题思路&#xff1a;采取后序遍历的好处是先遍历节点得到高度&#xff0c;然后再判断高度差是否大于一&#xff0c;如果是的话就返回-1&#xff0c;不是就返回两高度中较大的高度加一就是父节点的高度 具体代码如下&#xff1a; class Solution { public: int travel(TreeN…

Numpy重修系列(一) --- 初识Numpy

一、为什么使用Numpy&#xff1f; 1.1、简介 Python科学计算基础包&#xff0c;提供 多维数组对象 、派生对象&#xff08;掩码数组、矩阵&#xff09; 数组的快速操作&#xff08;数学计算、逻辑、形状变化、排序、选择、输入输出、离散傅里叶变换、基本线性代数、基本统计运…

利用Python进行大规模数据处理

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 利用Python进行大规模数据处理&#xff1a;Hadoop与Spark的对比 随着数据量的不断增长&…

Pytorch 学习路程

目录 下载Pytorch 入门尝试 几种常见的Tensor Scalar Vector Matrix AutoGrad机制 线性回归尝试 使用hub模块 Pytorch是重要的人工智能深度学习框架。既然已经点进来&#xff0c;我们就详细的介绍一下啥是Pytorch PyTorch 希望将其代替 Numpy 来利用 GPUs 的威力&…

23年新算法,SAO-SVM,基于SAO雪消融算法优化SVM支持向量机回归预测(多输入单输出)-附代码

SAO-SVM是一种基于SAO雪消融算法优化的支持向量机&#xff08;SVM&#xff09;回归预测方法&#xff0c;适用于多输入单输出的情况。下面是一个简要的概述&#xff0c;包括如何使用SAO-SVM进行回归预测的步骤&#xff1a; 步骤&#xff1a; 1. 数据准备&#xff1a; 收集并准…

Python获取上市公司报告,AI分析助力投资决策

折腾了几天&#xff0c;通过从巨潮信息网上获取上市公司的报告&#xff0c;然后实现调用大语言模型的API去分析报告内容&#xff0c;下面把相应的代码和过程分享给对这个感兴趣的兄弟姐妹们&#xff0c;希望能帮到大家。 1&#xff0c;首先去巨潮信息网首页&#xff0c;右上角…