一、浅层理解
进程是资源分配的最小单位,线程是CPU分配的最小单位——简单明了的说明了进程与线程的区别特点,然而在实际工作中并没有什么卵用。
二、多个维度下,进程与线程的优势对比
对比维度 | 多进程 | 多线程 | 结论 |
---|---|---|---|
数据共享 | 数据共享复杂,需要用IPC | 共享进程数据,数据共享简单 | 多进程 < 多线程 |
数据同步 | 数据是分开的,同步简单 | 因为共享进程数据,同步复杂 | 多进程 > 多线程 |
内存、CPU | 占用内存多,切换复杂,CPU利用率低 | 占用内存少,切换简单,CPU利用率高 | 多进程 < 多线程 |
创建、销毁、切换 | 创建、销毁、切换相对复杂,速度慢 | 创建、销毁、切换简单,速度快 | 多进程 < 多线程 |
编程、调试复杂度 | 编程调试相对简单 | 都很复杂 | 多进程 > 多线程 |
可靠性 | 进程之间不会相互影响 | 一个线程挂掉,会导致整个进程挂掉 | 多进程 < 多线程 |
分布式 | 适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单 | 适应于多核分布式 | 多进程 > 多线程 |
三、简单结论
-
当需要比较频繁的创建、销毁时,优先用多线程。
比如Web服务器,来一个连接创建一个线程,断了就销毁。
-
当需要大量计算的时候优先使用多线程。
所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。最常见的例子就是图像处理、算法处理。
-
强相关处理使用线程,弱相关使用进程。
什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。
一般的Server需要完成如下任务:消息收发、消息处理。“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。以上划分方式也非一成不变,需要根据实际情况进行调整。
可能要扩展多机分布式的用进程,多核分布式的用线程。
-
两者没有明显差别,推荐用自己最熟悉、最拿手的方式。
实际工作并不是非此即彼,往往都是“进程+线程”结合的方式。
-
消耗资源的对比:
从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。
-
通讯方式:
进程之间传递数据只能是通过通讯的方式,即费时又不方便。线程之间数据大部分共享(线程函数内部不共享),快捷方便。但是数据同步需要锁,对于static变量尤其注意。
-
线程的自身优势:
提高应用程序响应;使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上;
改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
四、实验测试结果 (由于实验并非本人完成,故只记录实验环境、条件以及结果。待老子有更多相关的感触会再次补充)
-
任务执行效率的比较
环境:单核、简单任务(打印字符串) 进程数/线程数 都是255
结论:任务量较小,多线程效率明显高于多进程。任务量较大时多线程不如多进程效率高。
-
在创建和销毁上的效率比较
-
单核
环境:单核,创建、销毁10万个进程/线程
结论:数据可以看出,多线程比多进程在效率上有10多倍的优势。但不能让我们在使用哪种并发模式上定性。
另外:预先派生子进程/线程比现场创建子进程/线程要复杂很多,不仅要对池中进程/线程数量进行动态管理,还要解决多进程/多线程对accept的“抢” 问题,在stevens的测试程序中,使用了“惊群”和“锁”技术。即使stevens的数据表格中,预先派生线程也不见得比现场创建线程快,在 《Unix网络编程》第三版中,新作者参照stevens的测试也提供了一组数据,在这组数据中,现场创建线程模式比预先派生线程模式已有了效率上的优势。因此:预先派生进程/线程的模式(进程池、线程池)技术,不仅复杂,在效率上也无优势,在新的应用中可以放心大胆地为客户连接请求去现场创建进程和线程。
-
双核
环境:双核,其它同上。
结论:双核处理器在完成任务量较少时,没有系统其他瓶颈因素影响时基本上是单核的两倍,在任务量较多时,受系统其他瓶颈因素的影响,速度明显趋近于单核的速度。
-
五、并发服务的不可预测性:
后续待补。(我只是似乎意会了,还不好言传。。。)
关于操作系统内部如何创建、销毁进程、线程,即为什么这些操作进程消耗会比线程大,还没有搞明白。日后待补。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。