线程,协程,异步编程模型

news2024/9/27 15:20:56

线程,协程,异步编程模型

1.线程编程模型

我们知道线程是 cpu 调度的基本单位。

如果是一个单核的cpu, 而且现在有3个线程需要执行。那么可能是 线程 1, 2, 3 通过 cpu分片, 轮流执行。

那么 如果不将 cpu 进行分片, 而是 线程 1,2,3 轮流执行,那么使用时间应该是和 cpu分片的时间完全是一样的。
并且只是切换了2次上下文。那么是不是这样执行的效率更高一些呢?多线程存在的意义又是什么呢?
在这里插入图片描述

那么提到这个问题,不得不提的问题是 I/O。磁盘的读写,网络数据的传输,音视频的输入输出,都包含IO。我们在编程过程中,最重要的IO 就是磁盘IO和网络IO。IO 是非常消耗时间的,它比执行其它程序更加消耗时间。

那么看一下IO 执行的过程是什么样的。有cpu ,硬盘,内存,这个时候想要进行文件的读取。
首先最容易想到的就是:cpu 直接读取硬盘上的数据,然后将数据放到内存中。也就是文件读取以后,会将文件的内容放到内存中。在整个IO 读取过程中,cpu是全部被占用的。如果是以这种方式进行读取的话,那么必然会造成 cpu分片和不分片的所需要的时间都是一样的。

在这里插入图片描述

但是实际的IO不是这样的。在IO 执行过程中,有一个非常重要的概念是:DMA。direct memory access。

在这里插入图片描述

在文件读取过程中,cpu 并不是直接操作硬盘,而是通过对DMA直接下发指令,让DMA完成文件的读取。也就是第一步就是 : cpu 向 DMA下发指令,指令中包含磁盘信息和要读取的文件的位置。然后DMA 告知硬盘进行文件的读取。读取的过程是将文件的内容加载到内存中。最终在读取完毕以后,硬盘会给DMA一个反馈,读取完成。DMA 最终以中断的形式告知CPU ,文件读取完成。然后cpu再去内存中取这一块变量的值,最终就拿到了文件中的内容。

然后我们看整个的过程,cpu 向DMA 下发指令以后,cpu 就处于一个空闲的状态了。在当前状态下,cpu 可以去执行其它的线程。

那么再来回顾当前的过程,首先是线程1,如果发现是 读取文件,那么cpu就会发送 指令到 DMA, 进行文件的读取。此时 cpu 是空闲的。然后假设同时 cpu 被线程 2占用了,然后发现又是读取文件,那么这个时候又会发送指令到DMA 进行文件的读取。以此类推。那么假设这时候这3个线程都在进行文件的读取了,这时候cpu又可以腾出来去干其他的事情了。DMA在这段时间会进行文件的读取。读取完成,并且给了cpu一个中断,那么线程1,2,3 又会占用cpu的资源,继续执行。

那么很明显在DMA执行的过程中,是不占用cpu的,cpu这个时候又可以去做其他的事情了,也就是被其他的线程占用。另外,DMA 进行读取的时候,是可以复用的。因为cpu的线路是有多条的线路的。所以说DMA可以充分的利用这些线路。最终实现并行的读取这些文件。通过以上这些,我们就可以大大提高cpu的利用效率。

因此如果线程想要提高效率,是和IO是密切相关的。而我们的程序中,往往都含有IO。既然线程都已经有这么高的执行效率的,那么协程和异步分别是什么意思呢?

2. 协程编程模型

线程是操作系统级别的概念。在程序中,如果我们想要开辟多线程,那么我们需要调用系统底层的api,才能进行多线程的开辟。在线程开辟的过程中,会比较浪费cpu的时间。并且在线程运行过程中,会有用户态和内核态的切换。这个切换,会占用较长的时间。因而会有一部分时间浪费在cpu切换这个时间点上。所以就有了协程。

协程是编程语言级别的。我们可以像使用线程一样使用协程。但是协程并不是线程,并不会告诉操作系统开辟了线程。因而协程是全程处于用户态的。因而协程可以称作是用户自定义的线程。因而协程可以大量的开辟,并且不用担心内核态和用户态的切换。

在一台机器上,我们可以开辟的线程是有限的,在正常的机器上,开辟的几百或者上千的线程就已经达到上限了。如果是利用go 去开辟协程的话,那么就可以随随便便开辟几千万个协程了。

3. 异步编程模型

看了线程和协程,我们最后来看一下异步。异步的编程其实是非常简单的。例如我们上面说的DMA读取磁盘就是异步的。在一些编程语言,比如 Node.js中,默认就是以 异步的方式来进行编程的。node.js 是单线程的,却能够应对高并发。最重要的原因也是它是异步的操作模型。也就是在单线程中会有很多的回调函数。

总结

无论你是一个初级开发者还是高级开发者,线程,协程,异步 都应该是你日常开发过程中绕不开的一个话题,所以作为软件开发者的我们,真的很有必要详细地了解。

鸣谢

线程/协程/异步编程模型

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

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

相关文章

Springboot中如何优雅的写好controller层代码

前言优雅?看到这个词,我第一反应是什么是优雅?怎么写才算优雅?一千个读者有一千个哈姆雷特,每个人的经验、阅历不同,也许理解就不同。我对优雅的理解很简单,就是简洁有效、容易理解,…

递归、迭代、单向快排的实现和两种优化方法

目录 快速排序 实现代码​​​​​​​ 时间复杂度 快排的优化 随机选择策略 三位取中法 非递归的快排 单向快排 快速排序 快速排序算法是基于分治策略的一个排序算法,其基本思想是对于输入的子数组进行分解、递归求解,最后合并。 分解&#xff…

Fiddler - 夜神模拟器证书安装App抓包

Fiddler- 夜神模拟器证书安装App抓包 文章目录Fiddler- 夜神模拟器证书安装App抓包前言一、软件安装1.Openssl安装1.1下载安装1.2配置环境变量1.3查看openssl版本,输入命令:openssl version2.夜神模拟器安装1.1 下载安装1.2工具准备,MT管理器…

React相关扩展一(setState、lazyLoad、Hooks相关)(九)

系列文章目录 第一章:React基础知识(React基本使用、JSX语法、React模块化与组件化)(一) 第二章:React基础知识(组件实例三大核心属性state、props、refs)(二&#xff0…

基于轻量级CNN的WHDLD多标签遥感分类识别系统

WHDLD数据成像波段包括R、G、B波段,数据覆盖包括6类地貌:裸地、建筑物、人行道、道路、植被、水域。数据集中包含4940张遥感影像及对应地物分类标记样本,影像大小为256x256像素,影像以jpg格式存储,标签数据格式为单通道…

高级前端常考手写面试题合集

解析 URL Params 为对象 let url http://www.domain.com/?useranonymous&id123&id456&city%E5%8C%97%E4%BA%AC&enabled; parseParam(url) /* 结果 { user: anonymous,id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字…

React(coderwhy)- 09(项目实战 - 1)

创建React项目 ◼ 创建项目的方式:create-react-app ◼ 项目配置:  配置项目的icon  配置项目的标题  配置jsconfig.json 新建jsconfig.json文件,在文件中粘贴以下内容{"compilerOptions": {"target": "es5","…

【数据结构趣味多】循环队列

目录 函数介绍及模拟实现 Front()函数 Rear()函数 enQueue()函数 deQueue()函数 isEmpty()函数 isFull()函数 循环队列模拟题 定义:把队列的头尾相连接的的顺序存储结构称为循环队列;循环队列的是由顺序表实现的。 为什么要使用循环队列&#…

Android MVVM之SavedStateHandle数据保存之详解与使用。

一、介绍 SavedStateHandle从名字可以看出,是保存状态的。这个类常和MVVM中的ViewModel搭配使用,对页面生命周期的数据状态的缓存与恢复做一个容器。这个容易相对onSaveInstanceState(Bundle)要更强一点,保存的数据类型也比较丰富&#xff0c…

算法刷题打卡第60天:回文链表

回文链表 难度:简单 给定一个链表的 头节点 head ,请判断其是否为回文链表。 如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。 示例 1: 输入: head [1,2,3,3,2,1] 输出: true示例 2: 输入:…

文本摘要,基于Pytorch和Hugging Face Transformers构建示例,有源码

​ 文本摘要的常见问题和解决方法概述,以及使用Hugging Face Transformers库构建基于新浪微博数据集的文本摘要示例。 作 者丨程旭源 学习笔记 1 前言简介 文本摘要旨在将文本或文本集合转换为包含关键信息的简短文本。主流方法有两种类型,抽取式和生…

Nodejs模块的封装(数据库Mysql)

文章目录项目结构本次演示需要使用的第三方包为1.app.js相关配置2.router下的user.js相关配置3.db/index.js文件相关操作4.router_handler下的user.js相关操作项目结构 后面的项目相关文件的创建步骤按照我写的博客从上往下一步一步来 本次演示需要使用的第三方包为 "cor…

【操作系统实验/Golang】实验4:虚拟内存页面置换算法

目录 1 实验问题描述 2 测试数据 3 流程图 4 实验结果 4 实验代码 1 实验问题描述 设计程序模拟先进先出FIFO,最佳置换OPT和最近最久未使用LRU页面置换算法的工作过程。 假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个…

【Leetcode面试常见题目题解】1. 两数相加

题目描述 本文是leetcode第2题的题解,题目描述摘自leetcode。如下 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个…

海外服务器提供商选择中存在哪些风险?

开展海外业务时,毫无疑问,选择一个高质量的海外服务器提供商可以省去不少麻烦。但是,同时有一些海外服务商需要避开。毕竟一个服务器不靠谱,这跟提供商有很大的原因。下面主要是关于低于标准的海外服务器提供商的一些潜在风险。 1…

ES6中字符串和数组新增的方法

ES6中字符串和数组新增的方法一、字符串中新增的方法1、模板字符串 (表达式、函数的调用、变量)2、repeat(次数)函数 : 将目标字符串重复N次,返回一个新的字符串,不影响目标字符串3、includes()函数 :判断字符串中是否含有指定的子字符串,返回…

mysql 8 新旧密码可以同时生效

在MySQL8.0以前版本,给MySQL更改密码,明确写到开发规范中,拒绝更在线更改更密码,因为在8.0以前操作非常麻烦且不太完美。 MySQL 8.0之前的处理方法: 1. 创建一个同样权限的帐号通过 show grants for ‘user_name’1…

通用vue编辑按钮和新建按钮事件逻辑

一、编辑按钮对话框 1.首先先创建一个文件夹page-model,在里面使用elemengt-plus提供的对话框组件el-dialog。 2.在page-model里面去使用之前封装好的form表单,就是之前封装好的搜索组件的hy-form 3.在form组件里面加一个插槽,对应 page-m…

微信小程序:会议OA项目-首页

目录 一、flex布局 Flex布局简介 什么是flex布局? flex属性 flex的属性 二、轮播图组件及mockjs的使用 三、会议OA小程序首页布局 一、flex布局 Flex布局简介 布局的传统解决方案,基于盒状模型,依赖 display属性 position属性 float…

CompletableFuture详解

CompletableFuture详解 概要 RunnableThread虽然提供了多线程的能力但是没有返回值。CallableThread的方法提供多线程和返回值的能力但是在获取返回值的时候会阻塞主线程。 上述的情况只适合不关心返回值,只要提交的Task执行了就可以。另外的就是能够容忍等待。 C…