永久免费素材网站,普通电脑怎么建设网站,网站怎么做跳转,张家港建设局官方网站作者 | 陆小风来源 | 码农的荒岛求生问#xff1a;如果一个和尚挑水喝#xff0c;两个和尚抬水喝#xff0c;三个和尚没水喝#xff0c;那么众人拾柴一定火焰高吗#xff1f;多线程一定能提高程序性能吗#xff1f;在计算机科学中#xff0c;这个问题的标准答案是“it d… 作者 | 陆小风来源 | 码农的荒岛求生问如果一个和尚挑水喝两个和尚抬水喝三个和尚没水喝那么众人拾柴一定火焰高吗多线程一定能提高程序性能吗在计算机科学中这个问题的标准答案是“it depends”看情况。计算机中的一切设计都是为了更加高效的利用硬件资源包括CPU、内存、IO等我们一样一样来了解一下。多线程与CPU多线程与CPU是程序员了解的最多的我们知道多线的目的之一在于充分利用多核但这里有个前提就是你要处理的任务真的能拆分成独立的子任务。举个例子如果你想对一个数组所有元素的和那么这个任务就可以拆分成为两个独立的子任务任务A计算前一半数组元素的和任务B计算后一半数组元素的和然后任务A和任务B分别交给两个线程来执行。如果是在多核系统下这类多线程并行处理将显著提高程序性能但这种使用多线程充分利用多核带来的性能提升是有上限的。道理很简单这就好比盖房子盖房子算是个不大不小的工程让一个人来完成也不是不可以但再来六七个人显然能加快工程速度但是再来成百上千工人来盖一栋房子可能速度反而会变慢毕竟资源是有限的(可用的工具等)人一多需要用在协调上的时间就会变多多线程也是同样的道理当线程数量超过某个临界点时操作系统就开始忙不过来了(频繁调度切换)我称之为三个和尚没水喝现象。但如果系统是单核的那么这种任务拆分则不会有什么效果因为不管你创建多少线程真正工作的CPU只有一个。当然也有可能我们根本就不能对任务进行拆分像计算斐波那契数列这类问题如果你不能计算出f(n-1)与f(n-2)的解那么你根本就没有办法计算出当前问题f(n)的解被拆分的两个任务A和B有前后依赖关系这时多线程就没有用武之地了。还有一种可能就是你的问题规模非常小如果这个数组是有几百几千个元素那么这时你使用多线程意义不大这时使用多线程带来的收益不足以抵消掉多线程带来的性能开销。多线程与IO多线程一定能提升程序的IO性能吗答案显然不是的。最简单的场景是这样的你的程序需要从一个速度极慢的网络链接上读写数据在这种情况下一个线程很可能就足以应付的过来创建多个线程反而可能对程序性能有损。相同的情况也会出现在磁盘上一个线程可能就已经将磁盘打满这时创建多个线程去读写文件显然不能加快程序的处理速度。而在服务器端程序员也使用多线程加快程序处理速度在这里一个典型的问题是阻塞式网络IO会导致调用线程被挂起而暂停运行此时最简单的方法就是创建多个线程每个线程处理一个请求但随着请求的增多创建的线程也会越来越多此时三个和尚没水喝现象开始出现IO多路复用技术可以很好的解决这一问题。当然如果你的场景是IO会阻塞住处理线程那么此时创建两个线程一个负责处理数据一个负责等待IO那么这显然会提高程序性能。多线程与内存内存其实和磁盘一样也是有读写带宽上限的但我们的程序一般都不会达到内存读写带宽上限这并不是瓶颈。瓶颈在于多线程共享的内存资源(数据)以及多核系统的cache一致性问题。一般来说对于多线程共享资源通常需要互斥访问然而为加快内存读写速度现代处理器中都有cache系统(L1、L2、L3)每个核心都有自己的cache这些cache会缓存内存数据也就是说一份数据可能会同时存在于内存以及各个核心的cache中这就会带来经典的数据一致性问题某个核心修改了cache中的数据后需要将其同步给其它核心这就要求cache系统中必须有能确保一致性的协议否则程序可能会读取到错误的(过期的)数据。然而这种同步是有性能损耗的多个线程频繁操作同一个变量可能导致处理器cache系统需要频繁在各个核心之间进行同步极端情况下多线程程序性能甚至比单线程要差。因此多线程之间能不共享数据就不要共享如果一定要共享那么就尽量将其控制在最小范围读写频次控制到最少。往期推荐Docker 那些事儿如何安全地停止、删除容器掌握 Dowanward API 的妙用轻松拿捏 kubernetes 环境变量云原生时代开发者应具备这5大能力实战 Kubectl 创建 Deployment 部署应用点分享点收藏点点赞点在看