多线程并非万金油

为了发挥多核机器的威力,可以用多进程或多线程的办法,由于多进程往往涉及共享内存等IPC问题,所以很多人都倾向于选择多线程,并以此为灵丹妙药。但多线程并非万能,它虽然使用方便,却也有硬伤——线程一死,会牵连其它。孙子曰“不尽知用兵之害者,则不能尽知用兵之利也”,不了解多线程的缺点,也就不能很好的使用它。

我们项目中有一个daemon,功能是转发并处理消息,为了能看到daemon运行的细节,我们还做了一个monitor线程,由该线程通过某个端口提供简单的web服务,这样就可以直接用浏览器查看daemon的运行状态(比如处理了多少消息,丢弃了多少等)。后来,monitor线程出现了一个bug,造成线程挂掉——于是造成了整个daemon挂掉。这下郁闷了,daemon本身是很重要的,而monitor是不那么重要的,现在是次要部分的bug拖累了重要部分的运行

这就是多线程程序的缺陷。如果多个线程做的是同样的事情,那还尚可;但如果多个线程,有的做这件事,有的做那件事,而且事情的重要程度不同,那不重要的线程由于代码错误或其他原因死了,其它的线程——包括执行重要功能的——也只能跟着挂。这在健壮性上肯定是不好的。apache采用多进程应该也是出于这样的考虑,因为它的module可能是用户自己写的,可能并不稳定,但由于module不稳定而挂掉整个apache,显然不应该。当然,apache2开始支持多线程,但即使这样,它默认还是多进程的,并没有整个倒向多线程。

也许有人会说:你代码写好一点,不要有bug,多线程不就没事了吗?首先,我们讨论的是软件健壮性的问题——怎样在坏了一部分以后其它部分还能工作,而不是软件正确性的问题——怎样写正确的代码。不是一个方向的问题,并不矛盾。其次,软件不可能没有bug,我们如果能把不同杀伤性的bug通过不同进程把它们隔开,就能降低影响,这跟挖掘bug的目标是一致的——都是为了增加软件的可用性。

所以,多线程并非万金油。为了健壮性,可以考虑把不同性质的任务分到不同的进程上,再由父进程统一管理。而在这些进程之下,可以再有多线程。当然,这样开发就复杂了。


相关文章

分类

8 Comments

Solstice said:

如果 monitor 的功能在 daemon 的(主)线程里实现(执行),它的 bug 同样会导致 daemon 挂掉。一样是“次要部分的 bug 拖累了重要部分的运行”,跟多线程没关系。

DongHao Author Profile Page said:

我的意思是monitor应该是daemon的一个子进程,这样monitor就算挂了,daemon也不会有事。

lee said:

刚才看了一篇数据库的拆分
这也相当于进程/线程的水平分割和垂直分割吧?
万变不离其宗啊~~~

dutor said:

受教

DongHao Author Profile Page said:

好像不太一样,数据库垂直分割是因为单机存不下了,多进程是为了健壮性。

woso said:

受教,多进程也不一定好,多线程也不一定好,具体问题得具体分析,没有银弹

DongHao Author Profile Page said:

“没有银弹”!

ericshang said:

确实各有利弊啊,之前公司是开发的内存库是多线程的,只要某个线程一挂,整个系统都要重新上电,加载,重建索引,影响业务好几分钟,如果数据量大的话几十分钟也是常事。
现在单位使用的是多进程的技术,采用共享内存,这样子某个进程挂了,只要监控进程在那么重新拉起也就是几秒钟的事情。好处不说自明。
google的chrome同样也是采用的多进程技术,当某个页面非法down了不至于我的其他页面也跟着歇菜,使用效果很好.

留言:

关于文章

This page contains a single entry by DongHao published on 07 13, 2010 3:11 PM.

旧事一则 was the previous entry in this blog.

[kernel] linux在多核处理器上的负载均衡原理 is the next entry in this blog.

Find recent content on the main index or look in the 存档 to find all content.