今天课上就项目的时间安排遇到了一个有趣的问题:内容如下:
求做这顿饭的最少时间?
计算机原理类比如下:
1.这个问题实际上是一个并发问题。 一个人力资源就相当于计算机系统中的线程概念!。(并且这个线程是一个并行概念下的线程,二者在工作时没有任何时间上的干扰),可见,线程是一个具有主动能力的物理存在。 换算成计算机中的话,它就是一个能量的释放者!! 也就是说只要它具有能量,它理论上是可以充当线程角色的。 那样的话,可以理解电池便是一个线程。 一个cpu内核采用超线程技术可以同时运行两个线程。 如今的个人pc基本可以做到4核8线程。 但是我们知道计算机中实际上是只需要一个供电来源的。 做个设想,将一个较大的电流通过一个并联电路将其分成两个电路,在线路的另一端,它并不会知道这个电流是否是某一个主干线路分离出来的。 也就是说,可以将一个大能源划分为众多个小能源,并且不失去物理特性。
2.西红柿炒蛋,红烧肉等就相当于一个进程。 它具有这样的特点: 同一个进程具有时间的先后依赖关系,不同的进程间理论上互不干扰。 但是硬件资源(锅,相当于内存上下文)有限, 所以多进程计算机需要上下文切换,正如这里只有一口锅一样。 (类似的,线程的概念跟进程的概念差不多,只不过她省去了上下文切换的中间环节。 比如,就西红柿炒蛋这个进程中,切洗西红柿 与 打鸡蛋可以同时进行。 他们共享硬件资源。 然而炒菜与打鸡蛋却不能同时进行,因为他们存在时间上的耦合关系)。
解决思路分析:
1.明确该问题是需要问最少花费的时间,也就是如何使得效率最大化的问题!! 或者说,在满足限定条件下的效率最大化的问题。
理想情况下,我们具有两个线程,二者均利用起来不浪费一丁点的时间,这便是最优的效果:
西红柿炒蛋: 1+5+2+5+1; 红烧肉: 1+10+30+1; 煮饭: 5+15
最理想环境下,能够达到的效率是: 76/2=38。 也就是说,我们的终极目标便是要将时间压缩到38分钟。
以上是考虑两个线程均一直工作的情况,然而实际情况有所区别。 因为实际上,线程工作的时候时间片,而时间片并不能很好的完成我们理想的切割!!
所以我们要以最大化并行的方式进行考虑。 如何做到能够最大化的并行? 我的考虑是,看到系统中有一个30分钟的任务,也就是系统的最大时间片。 在这个图中,另一个线程可以执行那些很小的时间片。 提高利用率。 在这种情况下(不考虑实际的时间耦合),能够达到的最好效果任然是38。 因为此时恰好能够找到这样的组合: 30+1+2+5=38。 注意最精彩的是,此时还不会发生硬件冲突。 因为组合关系是 洗锅+炖肉+洗西红柿 + 打蛋。
最后就是结合实际的情况考虑了。
第一步选择一个最大的时间片30(因为本质上我们希望尽可能多的让系统并行运行);
第二步,理清该任务的前置任务与后置任务:
炖肉前必须切肉; 炖肉前必须洗锅;
炖肉后必须洗锅;
就该任务而言,要实现最好的并发时间,那么最低的要求是1+10+30+1=42。 也就是说,在最理想的并发下需要42个单位时间。 或许有其他的方式比这个时间更短。 但是并不能成为整个系统的最低时间。 也就是说,在考虑实际情况后,42是整个系统的下限。 它已经取代了理想时间38。
第三步,这个单位时间已经超出了理想的时间,按理说这个应该可以作为最优了! 然而我们必须要考虑硬件资源的冲突。 也就是在这个并行途中,有一个线程必须因为硬件资源的原因而被阻塞!!。 直至占有该资源的线程放开这个线程锁,那么这个硬件资源才可被另一个线程享用!! 我想大概这就是多线程中锁的概念吧!!
可以发现,要优化一个问题最简单直接暴力有效的方法就是增加线程!!! 这在逻辑上是说得通的。 但是当线程数尝过了一定的数量,整个业务的重心将会转移到线程的管理上而非业务逻辑上,并且通常管理线程要复杂很多。 将来如果能够出现具有一定智能的线程,它能够管理自己从而适应整个系统,我想那一定很有趣。