IOS多线程一 多线程思想

多线程这个名词,大概在10年前刚踏入大学校园时就开始断断续续的听人说起,当时感觉他是一个神秘且强大的东西,感觉他是计算机领域的一个高级货。而一路走来,到了现在感觉这东西其实也没那么高高在上。现实生活中,有很多普通常见的地方我们都用到了多线程的思想。比如去银行办理业务,并不是大家排着一条队伍等着一个一个进行,而是有多个办理窗口在同时工作,由总的排号系统协调需要办理业务的人们排队等候,然后某个窗口有空闲的时候就会安排队伍最前面的人到该窗口办理。这些都跟计算机的多线程运行机制一样,银行就相当于一个多线程处理器(CPU),而每个过来办理业务的人们就好比一个一个需要处理的线程,系统级别的服务安排每个人到不同的分核处理器上去办理运行自己的相关业务。不断的有人进来,不断的有人办理完离开,我们计算机中的多线程其实也就是这样。

那么为什么要用多线程呢,首先,效率高是显而易见的,之前只有单核处理器的时候,很多系统就可以将一些工作划分为多个工作片段,然后让这些不同工作的片段交替在同一个处理器上执行,对于用户的表现就好像这些工作在同时进行。用户体验大大提升,当多核处理器出现的时候,这种处理方式就更加完美高效,对于用户来说也表现更佳,速度更快。而这只是概括性的初级原因,稍微接触一些程序开发你就会知道,很多情况下没有多线程,有些问题几乎是没有其他办法解决的,下面我就举几个典型的例子。

第一个,牵扯到界面操作刷新与大量数据运算的。比如我曾经做过的一个项目中的某个功能,音频EQ处理功能能。大家大可不必纠结EQ处理到底是什么,其实是一个专业音频处理中的部件,大家不用太关注,这里的EQ其实简单来说就有三个参数,根据这三个参数可以计算一条曲线,我们软件的功能就是在界面中用户可以设置这三个参数,然后根据用户设置的参数,使用我们的EQ算法计算一条曲线并且在界面中显示出来。需要说明一下的是,这个计算非常庞大,需要占用一定的时间和CPU工作量。而改变参数的方式有几种,用户可以在编辑框输入,那么每次输入新的参数,我们就会计算一次曲线,并且刷新显示界面。这倒是没有问题。但是用户还可以通过在界面中直接拖动点的方式来改变这三个参数,这下麻烦了,用户随便拖动一下这个点,这个点可能就会被改变了10多次甚至更多,我们需要平滑的将这个拖动改变的过程呈现给用户,如果拖动中的每次响应我们都按照之前方式处理,进行一次庞大的计算,并且重新刷新界面,那么只有一个结果,用户看到的是一卡一卡跳动的曲线,并不是平滑过渡的显示。而用户要是拖动的比较久的话情况会更糟糕,之前的响应一直排队等候处理,每次都是计算一次,然后刷新界面一次。用户的拖动操作响应很快,而处理很慢,就像高速运行的公路上出现了车祸,本来的三车道被占用了两车道,大家只能排着队从剩下的一个车道通过,而后面还有源源不断的车快速的行驶过来,而出口却只有一个,这样就会造成堵车。而这种堵车呈现的用户的结果就是界面卡顿,有可能用户已经拖动到了某个位置,而界面还在上个位置刷新,甚至用户已经结束了拖动操作有一段时间了,但是界面还在不停的跳动刷新,因为之前用户的操作响应还并未完成。这个时候多线程就要粉墨登场了。在这里我启动了一个专门进行曲线计算的线程,我们暂且称其为计算线程,主线程则仍然负责界面中的工作,主要是界面刷新显示。计算线程每0.2秒执行一次,每次查看公共数据,也就是那三个可以改变的参数是否有变化,有变化就开始使用新的参数计算。计算完成之后通知界面刷新。这样处理之后果然就流畅很多。可能在一秒之内用户拖动改变了10次数据,但是我们只取中间的几次进行计算并刷新界面,而且将计算与刷新界面分开两个线程进行,也大大提升了效率。计算的时候界面也可以同时刷新,而刷新界面的时候,计算线程也在不停的为下次刷新准备着数据。其实解决这个问题还用到了一些其他的技术,比如定时处理等,但是这些都是基于多线程,没有多线程其他的都是空谈。


IOS多线程一 多线程思想_第1张图片

如上图所示,以上例子中的EQ处理功能,在ShowMS(演出管理App)中可以查看并体会。该APP在App Store中已经上架,大家可以直接在App Store中搜索ShowMS下载查看,但是提醒一下,该APP只能运行在ipad上。

总结一下,只要是刷新界面的前置工作,而这个工作又需要大量时间的话那最好就启动另外一个线程来执行这个工作。

第二个使用到多线程的地方主要是网络请求层面的东西,网络这东西本来就有很多不确定因素,最直观的就是网速有时候不一定稳定,如果是无线网有时候也会受到干扰,而且很多情况下你也不能确定你发送请求的对方是否当前稳定在线,是否已经卡死奔溃。所以基于以上种种不稳定因素,网络请求的响应时间其实经常差别很大,快的时候几十毫秒就返回了甚至更快(1秒等于1000毫秒)。慢的时候对方被卡死,可能直到你设定的10秒20秒超时时间到的时候才能返回。所以这个时候我们发送网络请求,并且响应其返回的过程就不能简单的在主线程顺序执行。需要用到多线程,比如当你需要发送一条网络请求的时候,你就启动一个线程,在这个线程中组建报文发送然后等待其返回结果并进行处理。这样并不会影响其他线程,最主要的是不影响主线程刷新界面,用户不会以为你的软件卡住了界面不能操作了,当然还有更多的方式,比如组建和发送报文的过程是在本地进行,因为这块处理时间其实我们是可以把控并且也较短的,所以这块还可以在主线程进行,而将报文交于系统开始发送之后,我们就不在主线程处理了,单独启动一条线程等待该网络请求返回,并且在这个线程中处理返回数据。就好像公司老板不一定任何事情都需要亲力亲为,他开会将重要的事情安排之后,就离开了,留下一个副总在本地监督查看具体工作执行,而老板就好比主线程,继续去开展和推动其他事情顺利执行,而留下的副总就相当于你启动的另外一条线程。

第三种情况就是一些常运行的工作,比如保持网络连接的心跳功能,定时启动设备检测的功能,主页面的定时数据获取以及界面刷新。总之需要长期运行,并且需要耗费比较多时间的工作,需要另外启动一个线程在后台运行。当然耗费时间比较少也可以使用一些开发环境提供的定时器,而这种定时器在很多编译环境中其实仍然使用的是主线程,但是看起来好像是多线程一样,只是系统定了一个闹钟,闹钟一到点,系统就会在主线程上加载运行你定时器中设置的功能,所以如果这些功能耗费时间比较久,工作量比较大建议这种还是要酌情使用多线程处理。定时器其实相当于一个假的轻量的多线程。

以上几个地方只是一些比较典型的案例,其实多线程在其他很多地方也会用到。说了这么多但并未提及实质性的技术,是因为我觉得我们开发人员具备多线程思想比具备多线程技术更重要,对,多线程思想,什么时候时候我们该启动一条线程,漂亮的将一部分工作和代码划分出来,并且让程序运行的更高效稳定,而什么时候我们又不该启动一条线程,因为过多的滥用线程也会造成很多系统资源的浪费,线程间的同步与通讯也可能引入更严重的问题,让程序变的更加复杂且难懂。所以这个度就较难拿捏,只有大家在不断的实践中去体会。而关于实现多线程的技术,大家不要把他想的太难,接下来的章节,我会具体介绍关于IOS多线程实现的相关技术,请大家继续关注。

你可能感兴趣的:(IOS多线程一 多线程思想)