异步调用

那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)

守給你的承諾、 提交于 2019-11-29 12:30:03
一. 背景    在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并发问题,后面随着处理的系统业务越来越复杂,多线程再也回避不了了,也就借此机会深入研究了一下.Net中的多线程的处理方案。   发现在.Net领域中,多线程的处理大致经历了这么几个阶段:Thread→ThreadPool→委托的异步调用→Task→TaskFactory→Parallerl→异步编程模型(async和await)。   关注我博客的人会发现,早在 2017年6月份 的时候,就开始整理多线程问题了,大约用了6篇文章的来介绍了.Net中的线程的使用方法,主要是介绍相应类的实例方法的使用,有点帮助文档的意思了哦,最近多线程使用的相当频繁,借此机会重新结合一些实际业务系统介绍一下.Net领域的多线程问题,本次将整合原先的六篇文章(删除或覆盖更新)。 本质: 充分发掘CPU的性能,把一些并没有先后强依赖关系、且耗时代码块放到一个新的线程里去处理,那么原先按顺序执行的业务就会变成并行执行,让主线程继续往后执行,节约了时间了,提高了效率。 下面补充一下多线程在时间和空间上的开销: (一). 时间上: ①:开启或销毁一个线程都会通知进出中的dll程序集,让这些dll进行相应的操作。

同步异步

我是研究僧i 提交于 2019-11-28 17:25:30
阻塞,非阻塞,同步,异步 进程运行的三个状态: 运行,就绪,阻塞. 执行的角度: ​ 阻塞: 程序运行时,遇到了IO,程序挂起,cpu被切走. ​ 非阻塞: 程序没有遇到IO,程序遇到IO但是我通过某种手段,让cpu强行运行我的程序. 提交任务的角度: ​ 同步: 提交一个任务,自任务开始运行直到此任务结束(可能有IO),返回一个返回值之后,我在提交下一个任务. ​ 异步: 一次提交多个任务,然后我就直接执行下一行代码. ​ 返回结果如何回收? 给三个老师发布任务: 同步: 先告知第一个老师完成写书的任务,我从原地等待,等他两天之后完成了,告诉完事了,我在发布下一个任务...... 异步: 直接将三个任务告知三个老师,我就忙我的我,直到三个老师完成之后,告知我. 同步调用,异步调用 1. 异步调用 # 异步调用返回值如何接收? 未解决. from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time import random import os def task(i): print(f'{os.getpid()}开始任务') time.sleep(random.randint(1,3)) print(f'{os.getpid()}任务结束') return i if __name_

百万年薪python之路 -- 并发编程之 多线程 三

老子叫甜甜 提交于 2019-11-28 17:19:22
1. 阻塞,非阻塞,同步,异步 进程运行的三个状态: 运行,就绪,阻塞. 从执行的角度: ​ 阻塞: 进程运行时,遇到IO了,进程挂起,CPU被切走. ​ 非阻塞: 进程没有遇到IO 当进程遇到IO,但我通过某种手段,让CPU强行运行我的进程 提交任务的角度: ​ 同步: 提交一个任务,自任务开始运行直到此任务结束(可能有IO),返回一个返回值之后,我在提交下一个任务. ​ 异步: 一次提交多个任务,然后我就直接执行下一行代码. 返回的结果,应该如何回收? eg: 给三个老师发布任务: ​ 同步: 先告知第一个老师完成写书的任务,然后我在原地等待,等他两天之后完成了,告知我完事了,我才发布下一个任务........ ​ 异步: 直接将三个任务告知三个老师,我就忙我的,知道三个老师完成之后,告知我. 2. 同步调用,异步调用 同步调用: # 同步调用 from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor import time import random import os def task(i): print(f"{os.getpid()} 开始任务") time.sleep(random.randint(1,3)) print(f"{os.getpid()} 任务结束") return i

多线程(三)

流过昼夜 提交于 2019-11-28 16:19:50
多线程(三) 1.同步/异步and阻塞/非阻塞 进程运行的三种状态:运行,就绪,阻塞 从进程执行的态度: 阻塞:程序运行时,遇到了IO,程序挂起,cpu被切走 非阻塞:程序没有遇到IO,或者程序遇到IO,通过某种手段,让cpu强行运行该程序 从提交任务的角度: 同步:提交一个任务,自任务开始运行直到此任务结束(可能有IO),返回一个返回值之后,再提交下一个任务 异步:一次提交多个任务,然后就直接执行下一行代码 ps: 1. 同步与异步针对的是函数/任务的调用方式:同步就是当一个进程发起一个函数(任务)调用的时候,一直等到函数(任务)完成,而进程继续处于激活状态。而异步情况下是当一个进程发起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行当,函数返回的时候通过状态、通知、事件等方式通知进程任务完成。 2. 阻塞与非阻塞针对的是进程或线程:阻塞是当请求不能满足的时候就将进程挂起,而非阻塞则不会阻塞当前进程 3.阻塞调用是指调用结果返回之前,当前线程会被挂起(如遇到io操作)。函数只有在得到结果之后才会将阻塞的线程激活。有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。 #举例: 1. 同步调用:apply一个累计1亿次的任务,该调用会一直等待,直到任务返回结果为止,但并未阻塞住

异步调用导致的不同步问题

别来无恙 提交于 2019-11-28 08:37:34
业务场景:点击一个按钮的时候保存数据,同时打开一个弹窗带出保存的数据 基于这样的业务场景,最近遇到一个问题,是在ie11才发现的,点击按钮时候,后台打断点加数据库查询都验证数据是保存正确的,不过已经保存的数据是带不到弹窗页面的,问题比较奇怪,排查了挺长时间,最开始因为在ie才能重现的问题,在极速模式的360浏览器是没问题的,而且第一次点击时候没带出数据,第二次点击时候才可以带出数据,然后很容易让人联想到ie的缓存问题,不过调了大半天 加上ajax不缓存的代码,已经改成post请求,或者get请求连接后面加上一个时间戳参数都不奏效 $(function(){ //ajax不缓存请求结果 $.ajaxSetup({cache: false}); }); 然后经过和同事沟通,才发现自己跟错了方向,经过检查发现 保存的方法是用异步的 ,问题就出现在这里了,首先验证是不是由于异步导致的,在保存数据代码和打开弹窗页面的代码之间加一个alert提示,发现果然,关联alert弹窗提示之后,数据正常带出,所以确定是因为异步导致的 保存的代码,注意 async:true, ,这里是异步的,之前可能是考虑性能问题,改成异步的 $.ajax({ url:'${root}/saveOrUpdate.do', type:"post", async:true, success:function(result){

记录下最近看分布式系统设计的一些感想(下)

耗尽温柔 提交于 2019-11-27 16:10:28
上一篇文章讨论了分布式系统中的服务调用和异步消息,今天想在这两个的基础上讨论下分布式系统需要解决的问题,以及常见的解决方案。 其实分布式系统的出现和分布式系统面临的挑战归结到最终都是因为用户数量的急剧增长导致的,随着用户数量和活跃用户数的,应用服务和数据库服务的并发访问压力越来越大,我们不得不进行服务拆分,做数据库的拆分和读写分离。服务拆分之后可以让我们能对每个服务进行针对性的部署,核心服务得到更好的隔离。 对于服务的拆分,我们可以根据领域驱动设计的思想,将整个系统进行域的划分,找出我们的核心子域、支撑子域;服务拆分之后面临的一个问题是服务之间的调用,此时RPC就出现了(当然此前还有webservice等技术),而随着RPC的出现,又带来了新的问题,就是服务的治理,例如新的服务上线之后如何让其他服务发现,服务下线之后如何剔除,服务调用超时之后如何进行处理,还有就是服务的性能监控和可用率监控以及相应的报警措施。 同时,有些场景下可能我们不需要同步的调用一些服务,只需要异步通知就可以了,虽然现在的RPC框架也可以实现异步调用,但是当异步调用失败后还是会影响到通知的准确性,于是就有了消息队列。消息队列可以让我们实现服务之间的异步调用,当需要做某一个通知时,我们只需要往消息队列的服务方发送一条消息,用一个消费者去消费这条消息然后调用其他服务即可。同样每一项技术的引入都会给我们带来新的问题

nodejs中for循环和异步调用的那些坑

若如初见. 提交于 2019-11-27 13:35:03
在nodejs中for循环中是不能嵌套使用异步调用的,就像下面的: 我们定义一个post请求,用于接受前端发送来的文件,然后使用for循环对目录下的一些文件依次做一些异步调用事情(使用fs的stat) router.post('/uploadfile', function (req, res) { upload(req, res, function (err) { if (err) { return res.end("Error uploading file."); } for(let i = 0; i<req.files.length;i++) { fs.stat('./', req.files[i].originalname, function (err, stats) { //do somethins console.log(i); }) } res.end("File is uploaded"); }); }); 这里我们期望打印的log是从1到file文件的数量-1,可结果不会如我们所想,因为是异步调用,for循环不会按照要求执行,改进方式是使用递归调用 router.post('/uploadfile', function (req, res) { upload(req, res, function (err) { if (err) { return res.end(

Java 8原生API也可以开发响应式代码?

时光总嘲笑我的痴心妄想 提交于 2019-11-26 21:00:28
前段时间工作上比较忙,这篇文章一直没来得及写,本文是阅读《Java8实战》的时候,了解到Java 8里已经提供了一个异步非阻塞的接口(CompletableFuture),可以实现简单的响应式编程的模式,因此用这篇文章做个梳理。我是带着下面这几个问题去学习CompletableFuture这个接口的, CompletableFuture是为了解决什么问题而设计的? 它的使用场景是什么?开源软件中有实战使用案例吗? CompletableFuture的常用API都有哪些?如何使用? CompletableFuture和RxJava有什么不同? 这篇文章梳理下来,基本上可以回答前面四个问题,OK,我们进入正文。 基本概念 RPC(远程方法调用)的四种方式有:oneway、sync、future和callback,在dubbo或bolt这类通信框架中,默认使用的是sync模式(同步+阻塞),future和callback都属于异步模式,不过future模式在get的时候会阻塞,callback模式则不需要等待结果,有结果后服务端会回调请求方。 异步调用这类模式,比较适合的场景是IO密集型场景,要执行很多远程调用的任务,并且这些调用耗时可能比较久。以openwrite中的一个case为例:我发布一篇文章,需要给几个不同的写作平台创建文章,这时候我不希望这个过程是顺序的

.NET进阶篇06-async异步、thread多线程1

夙愿已清 提交于 2019-11-26 17:24:18
知识需要不断积累、总结和沉淀,思考和写作是成长的催化剂 异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出。纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人 本篇先做一个概述,列明一些基本概念 内容目录 一、进程和线程 1、进程 2、线程 多线程 后台线程 3、简言之 4、适用场景 二、同步和异步 1、同步 2、异步 3、异步编程 4、Async、Await 5、异步操作优缺点 三、小结 一、进程和线程 1、进程 我们打开计算机的任务管理器,会发现系统的很多个进程,每个进程独占CPU、内存、磁盘、网络等资源,是资源分配的最小单元。 多个进程之间是资源隔离 的,数据之间不能直接传递。一个exe运行一次就会产生一个进程,运行多次就多个,但他们之间数据互相隔离 2、线程 同样在任务管理器中我们也能看到线程, 一个进程是由多个线程组成的,且至少是由一个线程 ,那就是主线程。图中就可以看到线程的数量要比进程大的多 多线程 衡量一个人干活快,要么是一件事干的很快,要么是他能同时干很多事。计算机就是如此,以单核CPU类比单个人,理论上单位时间上只能运行一个进程里一个线程,只能干一件事。但线程有可能在某些操作比如读写磁盘时会等待,这时候磁盘在疯狂的运转,CPU却是闲置状态,直到磁盘读写完成才CPU才继续工作,所以空闲的这个时候它可以先去干别的事情,看起开就像单核它也可以同时干很多事

C#异步编程的实现方式(1)&mdash;&mdash;异步委托

冷暖自知 提交于 2019-11-26 11:05:20
异步的实现即多线程,一种简单的方式就是创建一个委托,然后异步调用它。 .Net Framework已经为我们提供了委托的异步调用方法。下面介绍三种使用委托实现异步的方法。 1、投票(IsCompleted属性) 首先定义一个委托: 1: public delegate string MyDelegate( int ms); Delegate类提供了BeginInvoke()方法,这个方法返回一个IAsyncResult接口,这个接口包含了该委托的相关信息,并且可以通过它的IsCompleted属性来判断该委托是否执行完成。下面是将要异步调用的方法: 1: static string DelegateMethod( int ms) 2: { 3: Console.WriteLine( "TakesAWhile started" ); 4: Thread.Sleep(ms); 5: Console.WriteLine( "TakesAWhile completed" ); 6: return "Hello world!" ; 7: } 下面是主线程的方法: 1: static void Imp1() 2: { 3: MyDelegate dl = DelegateMethod; 4: 5: IAsyncResult ar = dl.BeginInvoke(5000, null ,