`
vipshichg
  • 浏览: 266897 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

多线程的优点和代价

阅读更多

尽管面临很多挑战,多线程有一些优点使得它一直被使用。这些优点是:

  • 资源利用率更好

  • 程序设计在某些情况下更简单

  • 程序响应更快

资源利用率更好

想象一下,一个应用程序需要从本地文件系统中读取和处理文件的情景。比方说,从磁盘读取一个文件需要5秒,处理一个文件需要2秒。处理两个文件则需要:

5秒读取文件A
2秒处理文件A
5秒读取文件B
2秒处理文件B
---------------------
总共需要14秒

从磁盘中读取文件的时候,大部分的CPU时间用于等待磁盘去读取数据。在这段时间里,CPU非常的空闲。它可以做一些别的事情。通过改变操作的顺序,就能够更好的使用CPU资源。看下面的顺序:

5秒读取文件A
5秒读取文件B + 2秒处理文件A
2秒处理文件B
---------------------
总共需要12秒

CPU等待第一个文件被读取完。然后开始读取第二个文件。当第二文件在被读取的时候,CPU会去处理第一个文件。记住,在等待磁盘读取文件的时候,CPU大部分时间是空闲的。

总的说来,CPU能够在等待IO的时候做一些其他的事情。这个不一定就是磁盘IO。它也可以是网络的IO,或者用户输入。通常情况下,网络和磁盘的IO比CPU和内存的IO慢的多。

程序设计更简单

在单线程应用程序中,如果你想编写程序手动处理上面所提到的读取和处理的顺序,你必须记录每个文件读取和处理的状态。相反,你可以启动两个线程,每 个线程处理一个文件的读取和操作。线程会在等待磁盘读取文件的过程中被阻塞。在等待的时候,其他的线程能够使用CPU去处理已经读取完的文件。其结果就 是,磁盘总是在繁忙地读取不同的文件到内存中。这会带来磁盘和CPU利用率的提升。而且每个线程只需要记录一个文件,因此这种方式也很容易编程实现。

程序响应更快

将一个单线程应用程序变成多线程应用程序的另一个常见的目的是实现一个响应更快的应用程序。设想一个服务器应用,它在某一个端口监听进来的请求。当一个请求到来时,它去处理这个请求,然后再返回去监听。

服务器的流程如下所述:

  1. while(server is active){ 
  2.     listen for request 
  3.     process request 

如果一个请求需要占用大量的时间来处理,在这段时间内新的客户端就无法发送请求给服务端。只有服务器在监听的时候,请求才能被接收。另一种设计是,监听线 程把请求传递给工作者线程(worker thread),然后立刻返回去监听。而工作者线程则能够处理这个请求并发送一个回复给客户端。这种设计如下所述:

  1. while(server is active){ 
  2.     listen for request 
  3.     hand request to worker thread 

这种方式,服务端线程迅速地返回去监听。因此,更多的客户端能够发送请求给服务端。这个服务也变得响应更快。

桌面应用也是同样如此。如果你点击一个按钮开始运行一个耗时的任务,这个线程既要执行任务又要更新窗口和按钮,那么在任务执行的过程中,这个应用程 序看起来好像没有反应一样。相反,任务可以传递给工作者线程(word thread)。当工作者线程在繁忙地处理任务的时候,窗口线程可以自由地响应其他用户的请求。当工作者线程完成任务的时候,它发送信号给窗口线程。窗口 线程便可以更新应用程序窗口,并显示任务的结果。对用户而言,这种具有工作者线程设计的程序显得响应速度更快。

 

从一个单线程的应用到一个多线程的应用并不仅仅带来好处,它也会有一些代价。不要仅仅为了使用多线程而使用多线程。而应该明确在使用多线程时能多来的好处比所付出的代价大的时候,才使用多线程。如果存在疑问,应该尝试测量一下应用程序的性能和响应能力,而不只是猜测。

设计更复杂

虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂。在多线程访问共享数据的时候,这部分代码需要特别的注意。线程之间的交互往往非常复杂。不正确的线程同步产生的错误非常难以被发现,并且重现以修复。

上下文切换的开销

当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针 等,最后才开始执行。这种切换称为“上下文切换”(“context switch”)。CPU会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。

上下文切换并不廉价。如果没有必要,应该减少上下文切换的发生。

增加资源消耗

线程在运行的时候需要从计算机里面得到一些资源。除了CPU,线程还需要一些内存来维持它本地的堆栈。它也需要占用操作系统中一些资源来管理线程。 我们可以尝试编写一个程序,让它创建100个线程,这些线程什么事情都不做,只是在等待,然后看看这个程序在运行的时候占用了多少内存。

3
2
分享到:
评论
1 楼 steafler 2013-10-03  
老夫认为能用多线程还是用多线程

相关推荐

    VB的A*多线程例子

    在VB(Visual Basic)编程中,多线程技术允许程序同时执行多个独立的任务,从而提高应用程序的效率和响应性。A*算法是一种广泛应用的路径搜索算法,尤其在游戏开发、地图导航等领域,用于找到两点之间的最短路径。在...

    系统线程(内核线程)和用户线程区别 - 简书.pdf

    系统线程的优点是当有多个处理机时,一个进程的多个线程可以同时执行,缺点是由内核进行调度,创建和销毁系统线程的代价较高。 用户线程是用户程序中实现的线程,不需要内核支持,应用进程利用线程库提供创建、同步...

    python3爬虫中多线程的优势总结

    总结起来,使用多线程编程具有如下几个优点: 进程之间不能共享内存,但线程之间共享内存非常容易。 操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此,使用多线程来实现多任务...

    使用类C语言和MPI的多线程程序

    ### 使用类C语言和MPI的多线程程序 #### 概述 在并行计算领域,消息传递接口(MPI)是最广泛使用的编程模型之一。然而,由于每个MPI进程可用内存受限于所在计算节点的本地内存大小,这为大规模数据处理带来了挑战...

    Java多线程实例

    多线程的优点与代价: 1. **优点**: - 资源利用率更好:多线程可以充分利用多核处理器的计算能力,提高程序的执行效率。 - 程序设计在某些情况下更简单:如在网络编程中,每个连接可以由一个独立的线程处理,简化...

    dotnet-Gridpath是MIT许可的A星算法多线程2D实现

    “coryleeio-Gridpath-92aceb4”是项目的源代码版本,开发者可以通过阅读和研究源代码,学习如何实现多线程A*算法,以及如何在Unity3D环境中应用。源代码的开放性允许开发者进行二次开发,根据具体需求进行定制和...

    Linux中多线程详解及简单实例

    Linux中多线程详解及简单实例 1.概念 进程:运行中的程序。 线程:一个程序中的多个执行路径。更准确的定义是:线程是一个进程内部的一个控制序列。 2.为什么要有线程? 用fork调用进程代价太高,需要让一个...

    loadrunner线程和进程的区别[参考].pdf

    线程间通信和切换的代价低于进程,因此多线程可以提高程序的并发性,使得程序运行更高效。线程自身只拥有少量运行必须的资源,如程序计数器、栈等。 在LoadRunner中,Vuser的运行方式分为进程和线程两种: - **按...

    Java与线程.pdf

    - **优势**:提供了更强大的功能和更好的性能,适合复杂的多线程环境。 - **劣势**:较高的系统调用开销和内核资源消耗。 #### 三、Java线程的实现 Java中的线程实现主要采用了1:1的线程模型,即每个Java线程直接...

    基于线程与分布式排序对比实验的设计与研究.pdf

    本篇研究论文探讨了单线程、多线程以及分布式环境下排序算法的性能,以及它们在执行流程、算法代价和适用场景方面的对比,并提出了在分布式环境下采用多线程解决海量数据排序问题的方案。 首先,我们需要了解单机单...

    基于冗余多线程的体系结构级容错措施的研究与发展 (2009年)

    在总结各种体系结构级容错措施的技术特点以及目前的研究现状和发展趋势的基础上,论述了冗余多线程(RMT)体系结构研究的时代背景、典型架构设计方法和存在的问题,以及今后研究的方向和发展趋势。提出了今后应该从...

    SGM匹配算法.zip

    4. **多路径优化**:SGM的核心在于使用多条水平和垂直路径进行代价计算,每条路径都会引入一个不同的偏置,以抵消局部最小值的影响。这些路径的代价被加权平均,得到最终的视差代价。 5. **代价惩罚**:为了防止...

    PHP pthreads v3下worker和pool的使用方法示例

    合理使用worker和pool可以有效地平衡系统资源消耗和程序执行速度,实现高效的多线程编程。 总结来说,PHP pthreads v3的worker和pool机制是为了解决线程创建和销毁的性能问题,通过复用线程来提升程序效率。`Worker...

Global site tag (gtag.js) - Google Analytics