12.2 线程的优点和缺点

在某些环境下,创建新线程要比创建新进程有更明显的优势。新线程的创建代价要比新进程小得多(虽然与其他一些操作系统相比,Linux在创建新进程方面的效率是很高的)。

下面是一些使用线程的优点。

❑ 有时,让程序看起来好像是在同时做两件事情是很有用的。一个经典的例子是,在编辑文档的同时对文档中的单词个数进行实时统计。一个线程负责处理用户的输入并执行文本编辑工作,另一个(它也可以看到相同的文档内容)则不断刷新单词计数变量。第一个线程(甚至可以是第三个线程)通过这个共享的计数变量让用户随时了解自己的工作进展情况。另一个例子是一个多线程的数据库服务器,这是一种明显的单进程服务多用户的情况。它会在响应一些请求的同时阻塞另外一些请求,使之等待磁盘操作,从而改善整体上的数据吞吐量。对于数据库服务器来说,这个明显的多任务工作如果用多进程的方式来完成将很难做到高效,因为各个不同的进程必须紧密合作才能满足加锁和数据一致性方面的要求,而用多线程来完成就比用多进程要容易得多。

❑ 一个混杂着输入、计算和输出的应用程序,可以将这几个部分分离为3个线程来执行,从而改善程序执行的性能。当输入或输出线程等待连接时,另外一个线程可以继续执行。因此,如果一个进程在任一时刻最多只能做一件事情的话,线程可以让它在等待连接之类的事情的同时做一些其他有用的事情。一个需要同时处理多个网络连接的服务器应用程序也是一个天生适用于应用多线程的例子。

❑ 一般而言,线程之间的切换需要操作系统做的工作要比进程之间的切换少得多,因此多个线程对资源的需求要远小于多个进程。如果一个程序在逻辑上需要有多个执行线程,那么在单处理器系统上把它运行为一个多线程程序才更符合实际情况。虽然如此,编写一个多线程程序的设计困难较大,不应等闲视之。

线程也有下面一些缺点。

❑ 编写多线程程序需要非常仔细的设计。在多线程程序中,因时序上的细微偏差或无意造成的变量共享而引发错误的可能性是很大的。Alan Cox(Linux方面的权威,他撰写了本书的序)曾经评论线程为“如何立刻让自己自讨苦吃。”

❑ 对多线程程序的调试要比对单线程程序的调试困难得多,因为线程之间的交互非常难于控制。

❑ 将大量计算分成两个部分,并把这两个部分作为两个不同的线程来运行的程序在一台单处理器机器上并不一定运行得更快,除非计算确实允许它的不同部分可以被同时计算,而且运行它的机器拥有多个处理器核来支持真正的多处理。