架构设计多线程

上传人:wt****50 文档编号:34006438 上传时间:2018-02-19 格式:DOC 页数:20 大小:328.50KB
返回 下载 相关 举报
架构设计多线程_第1页
第1页 / 共20页
架构设计多线程_第2页
第2页 / 共20页
架构设计多线程_第3页
第3页 / 共20页
架构设计多线程_第4页
第4页 / 共20页
架构设计多线程_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《架构设计多线程》由会员分享,可在线阅读,更多相关《架构设计多线程(20页珍藏版)》请在金锄头文库上搜索。

1、架构设计:进程还是线程?是一个问题! 分类: 架构设计 2009-02-22 19:48 3568 人阅读 评论(18) 收藏 举报 就像莎士比亚的“To be, or not to be, that is the question”始终困扰着哈姆雷特,对于“进程还是线程?”这个问题,也经常困扰着那些进行软件架构设计的家伙。所以今天打算聊一下我对这个问题的体会。假如你还搞不清楚线程和进程的区别,请先找本操作系统原理的书好好拜读一下,再回来看帖。由于这个问题很容易引发口水战,事先声明如下:多进程和多线程,无法一概而论地说谁比谁好。因此本帖主要描述特定场景 (与我所负责的产品相关)下,进程和线程的

2、权衡经验,仅供大伙儿参考。由于特定场景是本帖讨论的前提,先说说我目前负责的产品的特点:业务逻辑比较复杂、业务数据量比较大、对数据实时 处理的性能要求比较高、对健壮性和安全性要求比较高、要求跨平台(包括操作系统、数据库)、某些情况下需要分布部署。上面说了一大堆,其实有不少的应用系统符合上述特点,比如:某些网络游戏服务器、某些金融行业的业务系统、某些电子商务的交易系统等等。如果你正在从事的是类似的应用系统的设计,希望我下面介绍的经验对你有帮助。进程颗粒度问题 大伙儿应该明白,进程和线程都是处理并发(concurrency)的手段。对于上述这种比较复杂的系统,如果你企图全部用进程(见 注 1 )或者

3、全部用线程(见 注 2 )来处理并发,估计会死得很难看。所以,关键问题就是如何在进程和线程之间进行平衡(也就是确定进程颗粒度的问题)。我个人建议,尽量以业务逻辑的单元来划分进程 。这样做的好处有如下几点:1、避免扯皮一般来说,某个固定业务逻辑的开发人员也是相对固定的。如果业务逻辑对应的某个进程崩溃了,测试人员容易快速定位肇事者,然后直接提交 Bug 给他/她。反之,一个进程搞得太庞大,N 多人掺和在里面,一旦进程崩溃了,相关编程人员之间很容易互相扯皮,不利于维护安定团结的局面;另外,由于测试人员经常搞不清楚 Bug属于谁,经常给错 Bug,也容易制造人民内部矛盾。从上面可以看出来,相对 细的进

4、程颗粒度能够避免一些管理上的麻烦。由于 XXX 经常教导我们:“稳定压倒一切 ”,所以该优点列第一条。2、健壮性、容错性一般来说,开发人员的水平参差不齐,优秀的毕竟是少数(具体参见“二八原理系列 ”的帖子)。所以难免会有菜鸟程序员搞出低级错误,而有些低级错误是致命的,会导致进程的崩溃。如果你是以业务逻辑划分进程,一个业务逻辑的进程崩溃,对其它业务逻辑的影响不大(除非是该业务逻辑的依赖方);因此就不会出现“ 注 2 ”提到的问题。3、分布式我常碰见的分布式部署需求,一般都是按照业务逻辑的维度来划分。比如系统中有一个认证模块,里面包含有敏感的用户认证信息。这时候客户就会要求把该模块单独部署在一台经

5、过安全加固的主机中(以防阶级敌人搞破坏)。如果是以业务逻辑为单位划分进程,要满足上述的部署需求就相对容易了(只要再配合恰当的进程间通讯机制,下面会提到)。另外,支持分布式部署还可以顺带解决性能问题。比如某个业务逻辑模块特别消耗硬件资源(比如内存、CPU、硬盘、带宽),就可以把它拿出去单独放一台机器上跑。4、跨编程语言这个好处可能很多人容易忽略。一般来说,每个编程语言都有各自的优缺点。如果你通过业务逻辑划分进程,就可以根据不同的业务逻辑的特点来选择合适的编程语言。比如:对于性能敏感的模块,我就使用 C+搞定;而对于一些业务逻辑密集型的模块,则使用 Java 或 Python 开发。进程间通讯(以

6、下简称 IPC)问题 既然不可能把整个系统放入一个进程,那就必然会碰到 IPC 的问题。下面就来说一下该如何选择 IPC。各种操作系统里面,有很多稀奇古怪的 IPC 类型。由于要考虑跨平台,首先砍掉一批(关于 IPC 的跨平台问题,我在 “跨平台开发 ”系列中会提到)。剩下的 IPC 类型中,能够进行数据传输的 IPC 就不多了,主要有如下几种:套接字(以下简称 Socket)、共享内存、管道、文件。其中 Socket 是我强烈推荐的 IPC 方式,理由如下:使用 Socket 可以天然地支持分布式部署;使用 Socket 可以比较容易地实现多种编程语言的混合(比如C+、Java、Python

7、 、Flex 都支持 Socket);使用 Socket 还可以省掉了一大坨“锁操作”的代码。列位看官中,或许有人在担心 Socket 的性能问题,其实大可不必多虑。当两个进程在本机上进行 Socket 通讯时,由于可以使用 localhost 环回地址,数据不用经过物理网卡,操作系统内核还可以进行某些优化。这种情况下,Socket 相对其它几种 IPC 机制,不会有太大的性能偏差。最后再补充一下,Socket 方式也可以有效防止扯皮问题。举个例子:张三写了一个进程 A,李四写了一个进程 B,进程 A 通过 Socket 方式发数据给进程 B。突然有一天,两个进程的通讯出故障了。然后张三就说是

8、李四接收数据出错;李四就说张三发送数据出错。这时候怎么办捏?很简单,随便找个 Sniffer 软件当场抓一下数据包并 Dump 出来看,问题就水落石出了。为啥还要线程? 上面说了这么多进程的好处,有同学要问了:“那线程有什么用捏?” 总的来说,使用线程出于两方面的考虑:性能因素和编码方便。1、性能因素由于某些操作系统(比如 Windows)中的进程比较重型,如果频繁 创建进程或者创建大量进程,会导致操作系统的负载过高。举例如下:假设你要开发一个类似 Web Server 的应用。你针对每一个客户端请求创建一个对应的进程用于进行数据交互(是不是想起了古老的 CGI :- )。一旦这个系统扩容,用

9、户的并发连接数一增加,你的应用立马死翘翘。上面的例子表明,跨平台软件系统的进程数要保持相对稳定。如果你的进程数会随着某些环境因素呈线性增长,那就相当不妙了(顺带说一下,如果线程数会随着环境因素呈线性增长,也相当不妙)。而根据业务逻辑的单元划分进程,顺便能达到“进程数的相对稳定”的效果。2、编码方面由于业务逻辑内部的数据耦合比较紧密。如果业务逻辑内部的并发也用进程来实现,可能 会导致大量的 IPC 编码(任意两个进程之间只要有数据交互,就得写一坨 IPC 代码)。这或许会让相关的编程人员怨声载道。当然,编码方面的问题也不是绝对的。假如你的系统有很成熟且方便易用的 IPC 库,可以比较透明地封装

10、IPC 相关操作,那这方面的问题也就不存在了。写到这里,看看篇幅有点超,就此打住。大伙儿如有不同看法,请到评论中拍砖。-注 1 所谓“全部用进程”,就是所有的并发都使用进程实现(因此每个进程只有一个线程)。这种设计在某些平台上(比如 Windows)会导致严重的性能问题。注 2 所谓“全部用线程”,就是所有的并发都使用线程实现(因此整个系统只有一个进程)。这种设计的健壮性极差(一个致命错会导致整个系统崩溃),而且更别提分布部署了。 版权声明 本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者编程随想 和本文原始地址: http:/program- 分

11、享到: 上一篇: 软件工程进阶之每日构建3:流程 下一篇: 如何成为优秀开发人员7:正确地做事(善用自动化) 查看评论14 楼 thomastangweixin 2011-05-06 09:26 发表 回复 13 楼 harry_helei 2010-07-21 12:47 发表 回复 来自实战的经验总结,胜过大口大口去肯书本。能解决实际问题的东西就是好东西。12 楼 nj_zxw10 2009-12-05 15:27 发表 回复 好文收藏,一看就是实战出来的宝贵经验,有楼主在我等菜鸟收获颇丰,万分感谢11 楼 procedure1984 2009-11-19 11:05 发表 回复 好文章!

12、10 楼 zhang_water 2009-04-25 12:57 发表 回复 我的使用经验:多进程,每个进程采用 select(libev)搞定!9 楼 avenir2008 2009-02-25 13:45 发表 回复 好 !8 楼 kickmeout 2009-02-24 11:30 发表 回复 这里写的很全,楼主看看吧 http:/ program_think 2009-02-24 12:03 发表 回复 楼上同学推荐的内容,主要是 Windows 平台上 IPC 类型的总结(确实比较全),对纯粹进行 Windows 平台开发的同学应该有帮助。 不过,假如要进行跨平台或者需要在 Uni

13、x/Linux 平台上开发,帮助就不是很大了。7 楼 cention 2009-02-24 09:47 发表 回复 当然得先设计一个稳定的 ipc 库,难道不用 ipc 就干起来了?6 楼 dch4890164 2009-02-24 09:22 发表 回复 呵呵不错,好文章 = IPC 机制你比较赞成 socket,于我心有戚戚焉 但是你按照业务逻辑来划分进程这点不敢苟同,或者只能说有可能在你所在行业是这样的。我更加赞成按照功能来划分,比如负责数据实时采集,用户数据交互,数据处理等。一般情况下多进程的程序,往往是分布式的,这样在某些程度上还可以将不同的节点有所侧重,比如某些节点负责数据处理,某

14、些节点负责数据采集,合理的控制各个节点的负载,并且与你其他观点比如扯皮等也一致。并且由于是多节点按照功能划分的话,即使某些节点 crash,其他节点或者热备节点也可以通过替代来拯救,但是如果你按照逻辑划分的话,如果采用热备的话,功能上会有冲突。Re: program_think 2009-02-24 12:00 发表 回复 功能和业务逻辑是两个维度。其实可以根据这两个维度的复杂度和耦合度来决定如何切分。 在某些情况下,有可能会同时在两个维度上分进程。比如: 某系统有业务逻辑 A、B、C。都需要有数据采集、数据分析、数据存储功能。 极端情况下,有可能分成 3*3 共 9 个进程。5 楼 anka

15、45o 2009-02-24 03:38 发表 回复 得看具体情况.4 楼 zhangqinghua 2009-02-23 23:41 发表 回复 非常好的文章,伯乐族收藏了! http:/3 楼 kuangyan1 2009-02-23 21:49 发表 回复 写的不错,但是在目前我所做的应用间或者进程间的通信一般还是用命名管道比较多一些,下次试试 socket2 楼 Analyst 2009-02-23 14:47 发表 回复 用进程不见得可以提高可靠性吧,如果一个系统中有一个进程 crash 了,依赖他的其他进程还能正常工作吗?相反由此引入的 RPC,多台物理服务器,多种异构平台,导致了部署的复杂性大大提高,可靠性肯定受影响。Re: program_think 2009-02-23 16:55 发表 回复 关于进程崩溃的问题,请看原文: “一个业务逻辑的进程崩溃,对其它业务逻辑的影响不大(除非是该业务逻辑的依赖方)” 关于 IPC 的问题,请看原文: “既然不可能把整个系统放入一个进程,那就必然会碰到 IPC 的问题。” 要想避免 IPC,除非整个系统只有一个进程。这么做无法满足分布部署1 楼

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号