这里的线程指通过linux的pthread_create而产生的原生线程,线程资源很宝贵,能被操作系统的任务调度器看见的(不是python gevent、go gorouine里的概念);
我们讨论以下两种模型;
- 多进程单线程模型(以下简称为多进程);
- 单进程多线程模型(以下简称为多线程);
多进程模型
优点
编程相对容易;通常不需要考虑锁和同步资源的问题。
更强的容错性:比起多线程的一个好处是一个进程崩溃了不会影响其他进程。
有内核保证的隔离:数据和错误隔离。
对于使用如C/C++这些语言编写的本地代码,错误隔离是非常有用的:采用多进程架构的程序一般可以做到一定程度的自恢复;(master守护进程监控所有worker进程,发现进程挂掉后将其重启)
多进程的案例
nginx主流的工作模式是多进程模式(也支持多线程模型)
几乎所有的web server服务器服务都有多进程的,至少有一个守护进程配合一个worker进程,例如apached,httpd等等以d结尾的进程包括init.d本身就是0级总进程,所有你认知的进程都是它的子进程;
chrome浏览器也是多进程方式。
redis也可以归类到“多进程单线程”模型(平时工作是单个进程,涉及到耗时操作如持久化或aof重写时会用到多个进程)
多线程模型
优点
多线程优点:创建速度快,方便高效的数据共享
共享数据:多线程间可以共享同一虚拟地址空间;多进程间的数据共享就需要用到共享内存、信号量等IPC技术;
较轻的上下文切换开销 - 不用切换地址空间,不用更改寄存器,不用刷新TLB。
提供非均质的服务
如果全都是计算任务,但每个任务的耗时不都为1s,而是1ms-1s之间波动;这样,多线程相比多进程的优势就体现出来,它能有效降低“简单任务被复杂任务压住”的概率;
适用的场景
1 线程间有数据共享,并且数据是需要修改的(不同任务间需要大量共享数据或频繁通信时);
2 提供非均质的服务(有优先级任务处理)事件响应有优先级;
3 单任务并行计算,在非CPU Bound的场景下提高响应速度,降低时延;
4 与人有IO交互的应用,良好的用户体验(键盘鼠标的输入,立刻响应)
多线程案例
桌面软件,响应用户输入的是一个线程,后台程序处理是另外的线程;
memcached
选用
单进程多线程和多进程单线程,2种模式如何取舍?
进程线程间创建的开销不足作为选择的依据,因为一般我们都是使用线程池或者进程池,在系统启动时就创建了固定的线程或进程,不会频繁的创建和销毁;
首先,根据工作集(需要共享的内存)的大小来定;如果工作集较大,就用多线程,避免cpu cache频繁的换入换出;比如memcached缓存系统;
其次,选择的依据根据以上多线程适用的场景来对比自身的业务场景,是否有这样场景需求:数据共享、提供非均质的服务,单任务拆散并行化等;
如果没有必要,或者多进程就可以很好的胜任,就多用多进程,享受单线程编程带来便利;
RCU的发明者,Paul McKenny 在《Is Parallel Programming Hard, And, If So, What Can You Do About It?》说过:
能用多进程方便的解决问题的时候不要使用多线程。
参考
ref:《Linux多线程服务端编程:使用muduo网络库》
ref:http://www.zhihu.com/question/19903801
ref:https://computing.llnl.gov/tutorials/pthreads/#WhyPthreads
Posted by: 大CC | 10OCT,2015
博客:blog.me115.com [订阅]
Github:大CC
dd