异步和多线程的区别

一、异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作 就没有必要异步了),可以继续自顾自的处理它自己的事儿,不用干等着这个耗时操作返回。.Net中的这种异步编程模型,就简化了多线程编程,我们甚至都不 用去关心Thread类,就可以做一个异步操作出来。


二、随着拥有多个硬线程CPU(超线程、双核)的普及,多线程和异步操作等并发程序设计方法也受到了更多的关注和讨论。本文主要是想探讨一下如何使用并发来最大化程序的性能。
  多线程和异步操作的异同
  多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别。
  异步操作的本质
  所有的程序最终都会由计算机硬件来执行,所以为了更好的理解异步操作的本质,我们有必要了解一下它的硬件基础。 熟悉电脑硬件的朋友肯定对DMA这个词不陌生,硬盘、光驱的技术规格中都有明确DMA的模式指标,其实网卡、声卡、显卡也是有DMA功能的。DMA就是直 接内存访问的意思,也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开 始自己和内存交换数据,在传输完成之后硬件会触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作正是异步操作的硬件基础。所以即使在DOS 这样的单进程(而且无线程概念)系统中也同样可以发起异步的DMA操作。
  线程的本质
  线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。
  异步操作的优缺点
  因为异步操作无须额外的线程负担,并且使用回调的方式进行处理,在设计良好的情况下,处理函数可以不必使用共享变量(即使无法完全不用,最起码可以减 少 共享变量的数量),减少了死锁的可能。当然异步操作也并非完美无暇。编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,与普通人的思维方式有些 初入,而且难以调试。
  多线程的优缺点
  多线程的优点很明显,线程中的处理程序依然是顺序执行,符合普通人的思维习惯,所以编程简单。但是多线程的缺点也同样明显,线程的使用(滥用)会给系统带来上下文切换的额外负担。并且线程间的共享变量可能造成死锁的出现。
  适用范围
  在了解了线程与异步操作各自的优缺点之后,我们可以来探讨一下线程和异步的合理用途。我认为:当需要执行I/O操作时,使用异步操作比使用线程+同步 I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.net Remoting等跨进程的调用。
  而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。但是往 往由于使用线程编程的简单和符合习惯,所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅,如果需要处 理大量的并发操作时就不合适了。

异步调用与多线程
异步调用并不是要减少线程的开销, 它的主要目的是让调用方法的主线程不需要同步等待在这个函数调用上, 从而可以让主线程继续执行它下面的代码.与此同时, 系统会通过从ThreadPool中取一个线程来执行,帮助我们将我们要写/读的数据发送到网卡.由于不需要我们等待, 我们等于同时做了两件事情. 这个效果跟自己另外启动一个线程来执行等待方式的写操作是一样的.但是, 异步线程可以利用操作系统/.Net的线程池, 系统可以根据吞吐量动态的管理线程池的大小.
=======================================================================
异步与多线程,从辩证关系上来看,异步和多线程并不时一个同等关系,异步是目的,多线程只是我们实现异步的一个手段.什么是异步:异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回.实现异步可以采用多线程技术或则交给另外的进程来处理
=========================================================================
线程池的实现方法与线程是不一样的.初始化时在线程池里的线程为0.当进程需要一个线程时,创建一个线程,由此线程执行用户的方法.需要注意的是,此线程 执行完后并不立即销毁,而是挂起等待,如果有其他方法需要执行,回唤醒进行处理.只有当它等到40秒(没有官方记录,有可能是其它数字)还没有任务执行时 才唤醒自己,并销毁自己,释放资源.当然,如果线程池中的线程不够处理任务时,会再次创建一个新线程进行执行.
异步有的时候用普通的线程,有的时候用系统的异步调用功能。有一些IO操作也是异步的,但是未必需要一个线程来运行。例如:硬件是有DMA功能的,在调用 DMA传输数据的时候,CPU是不需要执行处理的,只需要发起传输和等待传输结束即可。具体到.net平台,比如Socket的BeginSend,如果 是运行在Windows 2000以后的平台,在底层就会调用异步的完成端口来发送。
.Net中的异步执行其实使用的是异步委托。异步委托将要执行的方法提交到.net的线程池,由线程池中的线程来执行异步方法。
异步执行也得执行,不在当前线程执行,当然得去另外一个线程执行。异步通常用系统线程池的线程,通常情况下性能好些。(因为可以多次利用,申请时不需要重 新申请一个线程,只需要从池里取就行了。)异步是一种效果,多线程是一种具体技术。可以说,用“多线程”实现“异步”。
异步和多线程是两个不同的概念,不能这样比较.异步请求一般用在IO等耗时操作上,他的好处是函数调用立即返回,相应的工作线程立即返还给系统以供重用。 由于系统的线程资源是非常宝贵的,通常有一定的数目限制,如.net默认是25。若使用异步方式,用这些固定数目的线程在固定的时间内就可以服务更多的请 求,而如果用同步方式,那么每个请求都自始至终占用这一个线程,服务器可以同时服务的请求数就少了。当异步操作执行完成后,系统会从可用线程中选取一个执 行回调程序,这时的这个线程可能是刚开始发出请求的那个线程,也可能是其他的线程,因为系统选取线程是随机的事情,所以不能说绝对不是刚开始的那个线程。 多线程是用来并发的执行多个任务。

不过有个问题,异步有时优先级比主线程还高。这个特点和多线程不同。


---------------------------------------------------分割线:再补充一些-------------------------------------------------------


异步编程主要是针对某些耗时的操作、无需和用户交互、只执行一次无需返回结果等的操作。
何时使用多个线程
需要用户交互的软件必须尽可能快地对用户的活动作出反应,以便提供丰富多彩的用户体验。但同时它必须执行必要的计算以便尽可能快地将数据呈现给用户。如果应用程序仅使用一个执行线程,则可以将异步编程与 .NET 远程处理或使用 ASP.NET 创建的 XML Web services 结合使用,在使用自己的计算机的处理时间之外还使用其他计算机的处理时间,从而提高对用户的响应速度并减少应用程序的数据处理时间。如果您正在进行大量的输入/输出工作,则还可以使用 I/O 完成端口来提高应用程序的响应速度。

多个线程的优点
无论如何,要提高对用户的响应速度并且处理所需数据以便几乎同时完成工作,使用多个线程是一种最为强大的技术。在具有一个处理器的计算机上,多个线程可以通过利用用户事件之间很小的时间段在后台处理数据来达到这种效果。例如,在另一个线程正在重新计算同一应用程序中的电子表格的其他部分时,用户可以编辑该电子表格。

无需修改,同一个应用程序在具有多个处理器的计算机上运行时将极大地满足用户的需要。单个应用程序域可以使用多个线程来完成以下任务:

通过网络与 Web 服务器和数据库进行通信。
执行占用大量时间的操作。
区分具有不同优先级的任务。例如,高优先级线程管理时间关键的任务,低优先级线程执行其他任务。
使用户界面可以在将时间分配给后台任务时仍能快速作出响应。
多个线程的缺点
建议您使用尽可能少的线程,这样可以最大限度地减少操作系统资源的使用,并可提高性能。线程处理还具有在设计应用程序时要考虑的资源要求和潜在冲突。这些资源要求如下所述:

系统将为进程、AppDomain 对象和线程所需的上下文信息使用内存。因此,可以创建的进程、AppDomain 对象和线程的数目会受到可用内存的限制。
跟踪大量的线程将占用大量的处理器时间。如果线程过多,则其中大多数线程都不会产生明显的进度。如果大多数当前线程处于一个进程中,则其他进程中的线程的调度频率就会很低。
使用许多线程控制代码执行非常复杂,并可能产生许多错误。
销毁线程需要了解可能发生的问题并对那些问题进行处理。
提供对资源的共享访问会造成冲突。为了避免冲突,必须对共享资源进行同步或控制对共享资源的访问。如果在相同或不同的应用程序域中未能正确地使访问同步,则会导致出现一些问题,这些问题包括死锁和争用条件等,其中死锁是指两个线程都停止响应,并且都在等待对方完成;争用条件是指由于意外地出现对两个事件的执行时间的临界依赖性而发生反常的结果。系统提供了可用于协调多个线程之间的资源共享的同步对象。减少线程的数目使同步资源更为容易。

需要同步的资源包括:

系统资源(如通信端口)。
多个进程所共享的资源(如文件句柄)。
由多个线程访问的单个应用程序域的资源(如全局、静态和实例字段)。
线程处理与应用程序设计
一般情况下,要为不会阻塞其他线程的相对较短的任务处理多个线程并且不需要对这些任务执行任何特定调度时,使用 ThreadPool 类是一种最简单的方式。但是,有多个理由创建您自己的线程:

如果您需要使一个任务具有特定的优先级。
如果您具有可能会长时间运行(并因此阻塞其他任务)的任务。
如果您需要将线程放置到单线程单元中(所有 ThreadPool 线程均处于多线程单元中)。
如果您需要与该线程关联的稳定标识。例如,您应使用一个专用线程来中止该线程、将其挂起或按名称发现它。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值