发信人: headstream()
整理人: wenbobo(2002-12-24 09:16:49), 站内信件
|
任务,过程,和线程
在你很小的时候,你学习怎样一次完成一个工作,但到了成年,当然也许你已成 为父母辈了,这时,你就必须学会如何在同一时间做多个工作。例如,你是否发 现有多少次你在办公室里作弄过电话,E-MAIL 和客人?你也许正在办公室里和一 个人在谈话,这时电话铃响了,谈话就被电话打断了。也许正在打电话时,你又 来了新(重要的)E-MAIL,你必须中断你的电话。一旦处理完E-MAIL以后,你可 以接着打电话或者继续和办公室里的人谈话。如果等的时间太长了,电话另一端 的人可能会挂断电话,或者办公室里的人也许会生气离开。你必须决定如何花费 你的时间和花在谁身上。
在上面的例子中,你就是在进行多任务处理。你决定如何花费你的时间和计算机 对多任务进行时序安排类似。正如我们一天只有24小时,计算机的资源也是有限 的。看起来好像你在同时打电话和处理E-MAIL,但事实上,每次你只能将注意力 集中在一件事情上。实际上你是在不断变换注意力,只不过变换得足够快,就好 像你在同时做多个工作一样。当计算机处理多任务时,它从一个程序到另一个程 序的切换是非常快的,以至于使你认为,所有 的程序都在同时运行。
图一,从用户观点看单任务和多任务
假如你有一个克隆(可能叫多莉)的话,你就能同时做两件事。对于有多个CPU的 计算机,同时在每一个CPU上运行程序称为多重处理。有时,人们可替换使用多任 务处理和多重处理两个概念,但是,你不能在没有多个处理器的计算机上进行多 重处理。因此,如果你正在使用一台只有一个处理器的计算机,操作系统可以进 行多任务处理,如果你正在使用一台有多个处理器的计算机,操作系统既能进行 多任务处理又能进行多重处理。
在操作系统中,过程是一个逻辑上的任务。过程是在运行应用程序,启动某一系 统服务,和在Windows NT中启动某一子系统时产生的。每一个过程都有自己的专 用资源(例如自己的专用存储空间),只有拥有这个过程的应用程序才能访问这 些资源。这意味着,如果你产生了一个程序,在程序中用到一些数据,并且你也 没有建立任何形式的程序间数据共享机制或使用操作系统的程序间数据共享机制 ,那么就只有你的程序能访问这些数据。大多数Windows开发者都用COM对象简化 程序间的通信。如果你用的是Windows NT并且想共享数据,你可以使用内存映像 文件。但是这对于Geek Speak column来说技术性太强,所以让我们继续往下讲。
多任务处理:合作的和有优先权的
你能使用的多任务处理有两种基本方法:合作的,在这种方法中,正在运行的过 程必须为其他过程留出CPU时间片;有优先权的,在这种方法中,操作系统决定哪 个程序获得时间片。Microsoft Windows 3.x和Macintosh用的都是合作的多任务 处理,而OS/2,Windows 95,Windows NT,UNIX,和Amiga操作系统使用的是有优 先权的多任务处理。
合作的多任务处理
如果使用合作的多任务处理,每个程序必须允许其他程序使用CPU。使用合作的多 任务处理系统的应用软件都有一个特殊的码环,这个码环产生控制允许其他应用 软件的运行。如果每个人都按规则办事,这种方法会工作得相当好,但是当应用 程序不服从这一规则时,他“霸占”CPU。这意味着,终端用户不能转向其他应用 程序,使操作系统或应用程序出现“挂起”。
有优先权的多任务处理
在有优先权的多任务处理中,操作系统安排CPU时间,一个应用软件在任何时候都 有可能被操作系统暂停(先占)。这减轻了“一玩到底”的程序问题,因为操作 系统负责分给每个应用软件自己的时间片。
Windows 95对于32位Windows应用程序采用有优先权的多任务处理,为了能够向下 兼容,对于16位的Windows应用程序(为Windows 3.x写的应用程序)仍采用合作 的多任务处理。
线程
线程是一个能独立于程序的其他部分运行的作业。线程属于一个过程,获得自己 的CPU时间片。基于WIN32的应用程序可以使用多个可执行的线程,称为多线程。 Windows 3.x不能提供一种机制天然地支持多线程应用程序,但是一些为Windows 3.x编写应用程序的公司使用他们自己的线程安排。
基于WIN32的应用软件能在给定的过程中产生多个线程。依靠生成多个线程,应用 程序能够完成一些后台操作,例如计算,这样程序就能运行得更快。当线程运行 时,用户仍能继续影响程序。正如前面谈到的,当一个应用程序运行时,就产生 了一个相应的过程。那么应用程序就能有一个单独的线程等待键盘输入或执行一 个操作,例如脱机打印或计算电子表格中各项的总数。
在网络世界中,当你试图调整你站点的服务器的性能时,就要运行线程。如果你 使用的是IIS,你可以在服务器上设置对于每个处理器所能创建的线程的最大数目 。这样,就能在处理器间更均匀地分配工作,从而加速你的站点。
线程模式
现在,为了让你知道线程是什么和在哪能使用他们,让我们看一下使用线程时你 可能要运行的应用程序:ActiveX组件。ActiveX组件是独立于其他代码运行,基 于COM的代码。这听起来是不是很熟悉?当你使用ActiveX组件时,必须在操作系 统中注册。其中的一条注册信息就是,这个ActiveX组件是否支持多个线程,如果 支持怎样支持。这就是线程模式。
组件支持的基本线程模式有:单线程,单元线程,组合线程。下面几个部分将谈 谈每一种模式对组件来说意味着什么。
单线程
如果组件被标记(即注册)为单线程组件,这就意味着所有可执行函数(称作方 法)都将在组件的一个共享线程中运行。这就类似于没有生成独立的可执行线程 的应用程序。单线程组件的缺点是一次只能运行一个方法。如果多次调用组件, 例如调用组件中的存储方法,就会产生瓶颈,因为一次只能有一个调用。
如果你正在创建或使用一个ActiveX组件,建议不要使用单线程组件。
单元线程
如果一个组件被标记为单元线程,那么每个可执行的方法都将在一个和组件相联 系的线程上运行。之所以成为单元线程是因为,每个新生成的组件实例都有一个 相应的线程单元,每个正在运行的组件都有它自己的线程。单元线程组件要比单 线程组件要好,因为多个组件可以在各自的单元中同时运行方法。
自由线程
一个自由线程组件是一个支持多线程单元的多线程组件。这意味着多个方法调用 可同时运行,因为每个调用都有自己的运行线程。这能使你的组件运行快得多, 但也有一些缺点。运行在同一单元中的单元组件可以在单元中直接调用其他组件 的方法,这是一个非常快的操作。但是,自由线程组件必须从一个单元向另一个 单元调用。为了实现这一操作,WIN32生成了一个代理,用来通过单元界线。这对 于每个需要的功能调用来说就产生了系统开销,从而减低了系统的速度。每一个 访问自由组件的调用都有一个相应的代理。既然代理调用比直接调用慢,那么自 然会有性能方面的降低。
关于自由线程组件另一个需要注意的是:他们不是真正自由的。如果你创建了一 个自由线程组件。你仍必须确保组件中的线程完全同步。这不是一件容易的事。 只是简单地把你的组件标记为是自由线程的,并不能使你的组件支持多线程,你 仍要去做使你的组件自由线程化的工作。如果你不做这个工作,你的共享数据可 能被破坏。这里说明一下为什么:让我们假定你有一个方法计算某个数然后把它 写到某个变量中。此方法被传入一个初始值例如是4,在随后的计算中这个变量的 值增长为5。在方法结束时这个最后的值被写入到变量中。如果一次只有一个计算 过程的话,所有这些会工作得很好。然而,当数据正在被改变时,另一个线程试 图访问它,那么重新得到的数据就有可能是错误的。下面的图表说明了这一点。
为了修正这一错误,开发者为对象提供了线程同步。线程同步是在正在运行你想 保护的某一其他代码时运行的代码。操作系统并不先占这个代码,直到获得一个 可以中断的信号。如果你想了解更多的有关线程同步对象的详细内容,你不应该 阅读Geek Speak column!不,我的意思是,“注意看一下本文后面列出的参考阅 读文献”。
图二,共享数据被多线程访问搞乱了
组合线程
读到这,你也许会想既然每种形式的线程都有自己的优点和缺点,为什么不把不 同的线程模式结合起来使用呢?组合线程模式也许符合你的要求。一个被标记为 组合线程的组件既有单元线程组件的特性又有自由线程组件的特性。当一个组件 被标记为组合线程时,这个组件将总是在和生成它的对象所在单元相同的单元中 创建。如果组件是被一个标记为单线程的对象创建的,那么这个组件的行为将和 一个单元线程组件一样,并且它将在线程单元中创建。这就意味着,组件和创建 它的对象之间的调用,不需要一个为通信提供的代理调用。
如果新组件是被自由线程组件创建的,那么这个组件将表现得像一个自由线程组 件,但是它将在同一单元中运行,因此新组件能够直接访问创建它的对象(既不 需代理调用)。切记,如果你打算把你的组件标记为组合线程,你必须提供线程 同步保护你的线程数据。
-- 不是我不明白,计算机这玩意儿变化快
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.97.30.181]
|
|