进程间通信

进程间通信

我们提到过,当一个进程需要操作系统的帮助,它可以通过系统调用让内核来替它完成一些工作。迄今为止,我们已经熟悉了系统调用的工作机制,并且已经实现了不止一个系统调用。接下来你会发现,用户进程将会有更多事情依赖于内核。比如我们想实现一个文件系统,最起码读写硬盘的工作要求助于内核。这里我们可以逐渐地增加系统调用,但也可以采用另一种方案,就是将这些工作剥离出来,交给一些系统进程来完成,让内核只负责它必须负责的工作,比如进程调度。这种将内核工作简单化的思想,便是微内核的基本思想。而所有工作通过系统调用扔给内核态的做法,被称为宏内核。

在基于宏内核的操作系统中,完成具体任务时,用户进程通过系统调用让内核来做事,直来直去,我们之前已经很熟悉了。在基于微内核的操作系统中,这个过程稍微复杂一些。在完成具体任务时,内核的角色很像是个中介。就比如我们将要实现的文件系统吧,设想用户进程P读取一个文件,首先通过内核告诉进程FS,然后FS再通过内核告诉驱动程序(也是一个独立的进程),驱动程序读取硬盘,返回结果。这样一来,一项工作的完成变得有些曲折,需要多个进程协同工作。于是,进程间通信也就变得至关重要了。

到如今,我们的操作系统慢慢长大,接下来我们要用它来管理磁盘和磁盘上的文件并管理内存等,这些都要向应用程序提供接口,到了必须决定用微内核还是宏内核的时候了。怎么办呢?当然不能抛个硬币了事。我们不妨先找两个具体的例子来看看它们分别是怎么回事,看完了,明白了,再做决定也不迟。

微内核还是宏内核

微内核和宏内核的例子都非常好找。我们一直拿在手边的Minix,以及每天在用的Linux,便是两者的典型例子。Minix是微内核的,Linux则是宏内核的。

说起这两个例子,有一段轶事不能不提。那就是当年TanenbaumLinus一老一少的口舌之争。话说Linus写了个操作系统叫做Linux,使用的是宏内核,他把这个消息发在了comp.os.minix新闻组上,这时Tanenbaum说话了,把Linux批评了一通,年轻气盛的Linus于是发信回击,这样一来二去,为我们留下一段微内核与宏内核的经典争论。

争论的全部内容在这里我们就不全部转述了,读者感兴趣的话可以用搜索引擎很容易地搜到(或者在维基百科上看一下),我们把其中的重点说一下。在谈到微内核和宏内核时,AndyAndrew S. Tanenbaum)是这样说的:

老一点的操作系统都是宏内核的,也就是说,整个操作系统是一个运行在核心态的单独的a.out文件,这个二进制文件包含进程管理、内存管理、文件系统以及其他。具体实例包括UNIXMS-DOS VMSMVSOS/360MULTICS等。

另一种便是微内核,在这种系统中操作系统的大部分都运行在单独的进程,而且多数在内核之外。它们之间通过消息传递来通信。内核的任务是处理消息传递、中断处理、底层的进程管理,以及可能的I/O。这种设计的实例有RC4000AmoebaChorusMach,以及还没有发布的Windows/NT

我完全可以(但不必)再讲述一段关于两者之间相对优势的很长的故事,然而在实际设计操作系统的人中间说说就够了,争论实际上已经结束。微内核已经取得了胜利。对于宏内核而言唯一的争论焦点在于效率,不过已经有足够的证据表明微内核可以像宏内核一样快(比如Rick Rashid已经发表了Mach 3.0和宏内核系统的比较报告)所以那不过是喊喊而已罢了。

Minix是微内核的,文件系统和内存管理是单独的进程,它们运行在内核之外。I/O驱动也是单独的进程(在内核之内,但仅仅是因为Intel CPU的糟糕设计使得很难不这样做)。Linux是个宏内核的系统。这相当于向七十年代倒退了一大步。就好比将一个已存在的工作得很好的C程序用Basic重写一遍。在我看来,在1991年写一个宏内核的系统真不是个好主意。

以上前两段基本上可以被认为是宏内核和微内核的基本概念。从概念上我们不难猜到,宏内核看上去试图包办一切,而微内核恰恰相反,它的任务只是处理消息传递、中断处理、底层的进程管理,以及可能的I/O”,而其他事情都交给内核之外单独的进程来完成。

在这段文字中Andy不但阐述了宏内核和微内核的概念,摆明了对于这个问题鲜明的观点,而且他也毫不掩饰自己对宏内核的不屑。而且这种不屑让他认为Linux简直是技术的倒退。在随后的文字中,对于Linux的可移植性Andy也做了不客气的批评。也难怪Linus对此非常恼火。从Linus的第一个回复开始,这场争论开始变得精彩起来。

Linus的回复是这样开始的:

好吧,既然是这么一个主题,我恐怕不能不做回答了。向已经听了太多关于LinuxMinix使用者们道歉。我很乐意上钩(Andy说了这些话,好像在引诱Linus开始一场争论——笔者注),该是吵一架的时候了!

啊哈,看来Linus真的被激怒了,我仿佛看到了他挽起袖子的样子:)。是啊,看到自己辛辛苦苦的劳动成果被人冠以过时了的形容,谁还能平心静气呢?

针对微内核和宏内核之争,他是这样回应的:

是的,Linux是宏内核,我同意微内核更好些。如果不是你使用了具有争论性的主题,我可能会同意你大部分的观点。从理论上(以及美学上)讲Linux是输了。如果去年春天GNU内核已经做好,我可能不会这么麻烦地开始我的工作:问题是它没有做好而且到现在都没有。在已经实现这一方面Linux赢大了。

>> Minix是微内核系统……Linux则是宏内核的。

如果这是评价内核好坏的唯一标准,那么你是对的。你没有提到的是Minix的微内核实现得并不好,而且(内核内)多任务存在问题。如果我做一个多线程文件系统存在问题的操作系统,我可能不会这么快就声讨别人:事实上我会尽最大努力让别人忘掉我的失败。

这一段我觉得非常重要,因为看得出来,Linus内心还是承认微内核的优势的,而且他提到了美学aesthetical)这个词,因为的确,微内核的思想更加优雅,这在我们下文中的分析中也可以看到。不过尽管如此,他还是批评了Minix本身,认为它的微内核实现的并不令人满意。

在后来谈到可移植性的时候,Linus的话也颇具初生牛犊不怕虎的劲头:

可移植性是为不能编写新程序的人设计的

——我,现在(使用傲慢的语气)

真的很精彩不是么?我甚至感觉有点像在看武侠片,一老一少,出招拆招,虽是打架,但颇有章法。不难看出,刚刚这句我,现在(使用傲慢的语气)甚至带有一丝挑衅意味,看这句话我甚至在想像着Linus敲出这行字的时候该是带着怎样傲慢的神色——不过谁在年轻的时候不是这样气盛的呢?呵呵。

看过热闹之后,让我们来实地勘查一下,两种内核看上去是什么样子的。我们就以系统调用作为突破口,看看它们的代码。

posted @ 2009-05-25 09:37  博文视点(北京)官方博客  阅读(230)  评论(0编辑  收藏  举报