参考网址:https://blog.csdn.net/qq_27825451/article/details/78853119python
一、异步编程与多线程的区别算法
共同点:异步和多线程二者均可以达到避免调用线程阻塞的目的,从而提升软件的可响应性数据库
不一样点:编程
(1)线程不是一个计算机硬件的功能,而是操做系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,因此线程须要操做系统投入CPU资源来运行和调度。网络
多线程的优势很明显,线程中的处理程序依然是顺序执行,符合普通人的思惟习惯,因此编程简单。可是多线程的缺点也一样明显,线 程的使用(滥用)会给系统带来上下文切换的额外负担。而且线程间的共享变量可能形成死锁的出现多线程
(2)异步操做无须额外的线程负担,而且使用回调的方式进行处理,在设计良好的状况下,处理函数能够没必要使用共享变量(即便没法完 全不用,最起码能够减小 共享变量的数量),减小了死锁的可能。固然异步操做也并不是完美无暇。编写异步操做的复杂程度较高,程序 主要使用回调方式进行处理,与普通人的思惟方式有些 初入,并且难以调试。并发
这里有一个疑问。异步操做没有建立新的线程,咱们必定会想,好比有一个文件操做,大量数据从硬盘上读取,若使用单线程的同步操做天然要等待会很长时间,可是若使用异步操做的话,咱们让数据读取异步进行,二线程在数据读取期间去干其余的事情,咱们会想,这怎么行呢,异步没有建立其余的线程,一个线程去干其余的事情去了,那数据的读取异步执行是去由谁完成的呢?实际上,本质是这样的。异步
熟悉电脑硬件的朋友确定对DMA这个词不陌生,硬盘、光驱的技术规格中都有明确DMA的模式指标,其实网卡、声卡、显卡也是有DMA功能的。DMA就是直 接内存访问的意思,也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候能够不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开 始本身和内存交换数据,在传输完成以后硬件会触发一个中断来通知操做完成。这些无须消耗CPU时间的I/O操做正是异步操做的硬件基础。因此即便在DOS 这样的单进程(并且无线程概念)系统中也一样能够发起异步的DMA操做。async
即CPU在数据的长时间读取过程当中 ,只须要作两件事,第一发布指令,开始数据交换;第二,交换结束,获得指令,CPU再进行后续操做。而中间读取数据漫长的等待过程,CPU自己就不须要参与,顺序执行就是我不参与可是我要干等着,效率低下;异步执行就是,我不须要参与那我就去干其余事情去了,你作完了再通知我就能够了(回调)。异步编程
可是你想一下,若是有一些异步操做必需要CPU的参与才能完成呢,即我开始的那个线程是走不开的,这该怎么办呢,在.NET中,有线程池去完成,线程池会高效率的开启一个新的线程去完成异步操做,在python中这是系统本身去安排的,无需人工干预,这就比本身建立不少的线程更加高效。
总结:
(1)“多线程”,第1、最大的问题在于线程自己的调度和运行须要不少时间,所以不建议本身建立太大量的线程;第2、共享资源的调度比较难,涉及到死锁,上锁等相关的概念。
(2)“异步” ,异步最大的问题在于“回调”,这增长了软件设计上的难度。
在实际设计时,咱们能够将二者结合起来:
(1)当须要执行I/O操做时,使用异步操做比使用线程+同步 I/O操做更合适。I/O操做不只包括了直接的文件、网络的读写,还包括数据库操做、Web Service、HttpRequest以及.net Remoting等跨进程的调用。异步特别适用于大多数IO密集型的应用程序。
(2)而线程的适用范围则是那种须要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。可是往 往因为使用线程编程的简单和符合习惯,因此不少朋友每每会使用线程来执行耗时较长的I/O操做。这样在只有少数几个并发操做的时候还无伤大雅,若是须要处 理大量的并发操做时就不合适了。
二、在多线程编程和异步编程上的进步(以.NET和python语言为例进行说明)
多线程最大的问题在于“线程的调度”,而在.NET中引入了线程池的概念,避免人为建立多余线程,让系统进行分配;而Python语言中的多线程编程效率一直饱受诟病,所以python不多使用多线程,通常使用“协程”,后面会讲到。
异步最大的问题在于“回调”,.NET随着版本的升级,从多任务编程,到后面使用await-async关键字的提高,让人更加方便,不用注意到复杂的回调问题,用同步的思惟方式进行异步编程。python从3.4版本开始也开始使用协程和时间循环机制,从yield和yield from 语句中受到启发,解决了“回调问题”,而在python3.5版本中,也是使用了await-async关键字,进一步简化了编程。在这一方面,python和.NET有不少类似之处。(详细案例会在后面文章中展现)