通常会说:
进程之间的地址空间是独享的,而线程是共享进程的地址空间,线程的资源比进程小,创建线程比创建进程快,线程间切换快,线程间通信快,线程资源利用率好.
下面做个补充:
1,线程挂则可能导致进程挂,稳定性差。对长时间运行的serve程序,这一点尤为重要。所以为了兼顾稳定性和性能,很多程序中采用multi-process +multi-thread.
2,线程受进程资源的限制,比如:ulimit -a可以看到的若干。
3,线程在同一进程内,方便的共享内存。进程则需做内存映射,相关的互斥量等也需要设置为进程共享。
4,同步相对复杂,不利于资源的管理和维护。
在开发经验中你会懂得:
1)web服务器都支持master-worker多进程架构
2)apache还在worker进程里采取主线程,监听线程,线程池的架构。
3) lighttpd/nginx用epoll I/O复用取代Apache的多线程架构,线程切换少了,进程稳定了。
4) I/O复用接口效率高,并发量不再受线程数限制了。
5) 多进程更有利于权限控制,通常web服务器的worker进程都会setuid到普通用户,避免拥有过高权限受到漏洞攻击,而master进程拥有root权限才能bind 80。
6) 多进程有利于架构级别的扩展,更利于部署,但多线程并不是影响这个问题的关键因素。
7) 如果功能点不会变动或者变动小,做在线程池里让功能更加内聚了。
但如果是一个通用模块,把它做成可扩展的独立进程,甚至通过程序架构设计动态库加载,可配置回调等等,让它为更多的项目服务,做成进程当然更合适。
另外一个问题:
在使用共享内存的时候,要注意什么?除了共享内存没有同步机制,使用共享内存的时候,程序员要自己实现同步,还有别的要注意么?
1,创建任何东西先带着CREAT | EXCL去创建,失败了则直接打开,这是原子性必备的。
2,共享内存初始化之前如何同步? 设置mode的X位后开始初始化共享内存,结束后取消X位,任何进程打开共享内存后stat轮询检查X位是否复位,复位后才可以开始操作。
3,进程共享的mutex, cond,你应该都会用,不会用看书或者man pthread.h找接口。
4,共享内存可以做成chunk list内存块链表,一般用于在共享内存中建立树型数据结构,或者建死的多级hash表,或者循环队列,都是可以做的。
5,其他同步机制,信号量,FIFO, 等等,反正用途比较小,看情况用。