多线程技术在VB 5中的应用

西安第四军医大学生物医学工程系电子学教研室 焦纯 杨国胜 王健琪 陈马丁

返回主页

摘要:多线程技术是Win95系统的一大特色。本文深入阐述了Win95进程的多线程机制,并详细讨论了在VB5中实现多线程并行性多任务的方法。

关键词 Win95 VB5 多线程 进程 多任务 API

        VB5作为应用程序的强大开发平台,其新增的支持多线程组件的功能为大型企业和远程应用提供了坚实的基础和广阔的应用前景。通过多线程组件技术来优化远程服务和客户机/服务器应用程序已经成为一种重要的应用程序优化方案。

一、Win95系统的多线程机制及其与WIN 3.x多任务机制的比较

        支持基于多线程(Multi-thread)的多任务处理是Win95系统比16位的Windows3.x单纯划分CPU时间的多任务处理优越的重要标志之一。它的预先抢占式多任务和多线程处理使Win95系统的响应和平稳的后台处理性能得到很好的改善。

        Windows 3.x操作系统实现的多任务被称作协作式多任务。协作式多任务的关键是每个单独的应用程序决定何时放弃处理器以让另外一个可能正在等待处理的应用程序实现处理。这使得Windows 3.x平台易受到不完善的应用程序的影响,这种应用程序会在实现一些漫长费时的处理或干脆陷入死循环中让其他应用程序也被困住而不能运行。另外,在Windows 3.x中,所有应用程序都是单线程的,即在运行时的每个时间点上只有一条执行路径。Windows 3.x的这种单线程协作式多任务机制显然在相当多的时候只能提供一种低效率和不够安全稳定的多任务运行环境。

        对于32位Windows 95,操作系统在本质上发生了变化。由预先抢占式多任务代替了协作式多任务。所谓预先抢占式多任务就是由操作系统而不是应用程序自身来决定何时把处理器从当前的应用程序撤出,并把处理器交给另一个正在等待处理器的应用程序来使用。这与当时拥有处理器的应用程序是否准备放弃处理器给另外的应用程序使用无关,处理器不必经过应用程序的同意就被操作系统夺走了。这样操作系统才能使多个操作大数量任务的应用程序在每个任务上取得大致相同的进展。操作系统的这一手段阻止了某个应用程序在私占处理器时使其他应用程序难以执行的可能性。

        一个Win95的32位应用程序总是由一个进程、一个主线程和若干个子线程组成,它的一个突出特点是支持多线程,即在竞争CPU的线程分配CPU时间。进程(Process)是一个运行例程,当一个应用程序调入内存准备执行时,它就产生一个进程。一个进程由若干EXE文件的代码和数据块组成,它们被存放在逻辑上达4GB的线性地址空间内,EXE所需的DLL(动态链接库)也将它们的代码和数据装入到此空间内。进程是静态的,即一个32位的Win95进程并不执行什么指令,为了让进程完成一些工作,进程必须至少占有一个线程,由线程负责执行包含在进程的地址空间中的代码。进程占有的资源(包括其内的线程)都随着进程的生成而产生,都随着进程的终止而被系统撤消。

        线程(Thread)是进程中的一个执行单元。同一进程的各个线程对应于一组CPU指令、一组CPU寄存器以及一个堆栈。进程空间存放的代码由线程来执行,每个进程中至少有一个线程在执行其地址空间中的代码。对于同一进程中的多个线程来说,它们可以共享地址空间和所有的处理器资源,包括线程存取令牌、基本优先级、对象句柄和其他资源等。同时,线程的执行与否,是看其处在挂起态还是激活态。处于激活态的各线程由调度程序决定哪个线程将得到下一个处理器时间片。下一个时间片总属于那些准备执行的线程中优先权最高的一个。

        在Win95中,存取不可共享的资源、代码段称为临界区。需要注意的是,为保证代码的正确执行,每次只能有一个线程在临界区段中执行。在一个线程正在向一个文件写入数据、更新数据库或修改可共享的变量时,其他线程不允许存取同一资源。另外由于Win95为每个进程创建2GB的进程空间,操作系统DLL和其他DLL被装入其上的2GB地址空间中,这样每个进程都有自己的存储空间的拷贝。这种临界区和2GB地址空间的设置都大大提高了Win95多任务环境下的安全性和稳定性。
允许有多个应用程序同时运行的能力,也就具有了对单个应用程序,在任何时刻都有多道线程在执行的技术。线程对应用程序来说就像应用程序对操作系统一样。如果某个应用程序有多道线程在运行,基本上就有多个“应用程序”在整个应用程序中运行。这就允许应用程序同时完成多项工作。

        基于线程的多任务系统,使得同一进程的两个或多个线程可以同时运行。对用户而言,多任务的优点是能够同时打开和运行多个应用程序。对应用程序开发者来说,Win95多任务的优点是能够创建多线程的应用程序以及执行多线程的进程,这样就便于各任务之间的协调操作和运行。例如,可以将整个进程划分为接受用户输入的线程、数据处理线程、接受远程信息线程、外围处理线程等,这样使得每个线程都同时运行,充分利用了CPU的空闲时间片,使得进程(应用程序)的整体运行效率得到较大提高。

        另外,线程仅需要很少的附加资源开销,并且线程的创建比进程快。用多线程实现并行性多任务,避免了用多个进程(即多个应用程序)实现并行性的缺陷。同时,由于同一进程的所有线程共享同一内存(这些线程仅具有不同的堆栈和寄存器内容),故不再需要特殊的数据传送机制。显然,多个线程在相互通信时,完全不需要建立共享存储区或共享文件。

        正是线程的低资源开销和高的运行效率,使得它相对于进程式并行性多任务具有更大的优势和更为广阔的应用前景。多线程技术在远程应用和客户机/服务器方式的应用中占据着举足轻重的地位。

二、VB5中的多线程技术

        Win95中的多线程是一种标准模式,它得到了VC++或BC++等开发工具的很好支持。但是它的工作原理和编程机制却是一种针对纯C++程序员的专利。对VB这种舍弃了指针等复杂数据类型的以简便和实用见长的开发工具却并不完全适合。

        在VB5中能多线程运行的应用程序必须满足以下的条件-即这个应用程序必须放弃用户交互,即不能有类似于窗口之类的用户界面。因而,微软在VB5中实际上不允许创建这种复杂的标准多线程应用程序。

        但是VB5为了远程应用程序和客户机/服务器的分布式处理的考虑,允许通过一种称为“单元模型”(apartment-model)的多线程模式来创建多线程组件(如ActiveX EXE)。在这种模式中线程的同步问题通过给每个线程一套组件的全局变量并完全除去全局资源(如窗体)来避免。用单元模型线程,每个线程都有各自要使用或访问的内存对象及对象变量的拷贝。即每个线程都有自己的单元,单元里放着线程要使用的对象,线程就被限制在自己的单元里。这样就把程序员从不得不考虑线程间协调使用变量和资源的难题中解脱出来。可见,VB5在增加线程功能的同时,也简化了内存对象的管理和线程同步。

        从以上可以得出这样一个结论,即应用VB5来获取多线程效果是实际可行的,只要创建一个进程外的ActiveX服务器,并使用ActiveX的自动控制功能来为它工作就可以了。

        可见,VB5应用程序和DLL中的线程与通常形式的多线程方式不同,VB5中的线程特性使得它区别于支持标准多线程处理的VC++或BC++开发工具。

三、VB5的多线程应用与编程

        在分布式处理或远程自动化的客户机/服务器方式的应用中,为提高系统的效率经常需要优化程序。以一个远程应用程序为例,如果客户请求的远程对象是多任务而且远程应用程序已在服务器上运行,那么在创建对象时客户应用程序响应最快。然而,远程应用程序中的多任务对象会为客户导致问题。例如,如果多个客户同时使用一个远程应用程序,其中一个客户触发了内部错误,使远程应用程序异常退出,那么其他客户使用的对象也被清除。类似地,占用应用程序的操作也会给多任务对象客户导致问题:所有客户都必须等待每一个操作完成。当远程应用程序同时为多个客户程序服务时,这个问题就十分突出,将显著降低系统的性能。

        由于VB5支持多线程的组件技术,可以用多线程来优化多任务对象的性能。在多线程下,每个新的多任务对象都独立运行-即单个客户不能占用其他客户的远程应用程序。

        在实际创建多线程的多任务对象时有一个很大的限制-即应用程序不能包含窗体。这意味着应用程序无法与用户交互。但是可以通过用多线程应用程序发放单用途应用程序对象的运行实例来解决这个问题,在VB5中,这种类型的多线程应用程序称为线程池管理器。

在中文VB5中建立一个多线程的应用程序的基本步骤如下:
(1) 从“工程”菜单中选择项目“工程1属性”。
(2) 在“工程属性”对话框中选择“ActiveX EXE”工程类型,“启动对象”下拉框中选择“无”,此时“执行无用户界面”的复选框有效,选中它。
(3) 在“线程缓冲池”项中选择于包含的线程数。
(4) 加入程序运行需要的功能代码。
(5) 编译此项目。4
编译时的工程属性设置具体如下图。

tu1.gif (7840 字节)

        多线程应用程序可为每个对象分配一条线程或固定数量的线程,当新对象创建时循环使用它们。作为一个缓冲的线程池管理程序,可以利用它为客户端应用程序维护打开的自动化服务器实例。在这种方案中,如果客户端应用程序需要使用某个对象,它们需要向缓冲池管理程序请求使用一个线程。缓冲池管理程序将检查缓冲池,并决定是否准许请求。这种方法具有以下优点:
(1)它避免了每个客户端请求带来的大量自动化服务器创建费用。因为缓冲池通常是在客户端需要服务器之前就创建完毕的。
(2)根据客户端请求的频率、潜在的客户端的个数以及服务器任务所需的时间,创建的缓冲池的大小比一对一的客户/服务器分配方案通常要小得多(而且缓冲池的大小是可以随时进行调整的)。如果缓冲池的大小为 5 个线程,那么在通常情况下是能够满足 60 个客户端的需求的。
(3)它限制特定类型的服务器不得超出规定的个数,该阈值是由服务器管理员确定的。这是一种非常有用的性能调节参数,它还可以防止服务器被请求高峰的低优先级服务器滥用。

        自动化服务器可以作为客户端运行在同一台计算机上。它也可以在远程计算机上运行,从而得到分布式处理带来的强大处理能力以及共享的网络服务器带来的多用户访问特性。

        由于服务器远程应用程序不具有通常意义上的用户界面,那么提供状态监控的另一种方法是由服务器提供状态方法,并由单独的监控程序来对服务器的状态进行查询。

        需要注意的一点是,由于关于线程的函数VB5本身并没有提供,必须借助于Win95系统提供的API应用程序接口函数集,这些函数必须先定义后使用。使用中也需要注意它们的参数传递问题,由于这些函数大部分是为C++程序员设计的,其中就涉及到一些参数类型转换的技巧。可以说,API接口为VB提供了最宝贵的高级功能的基础,在很多VB自身没有解决方案的情况下,调用API接口函数往往几乎是唯一的可选方法。

四、结束语

        VB5通过自身特有的“单元模型”多线程模式为程序员们提供了创建多线程组件的功能。通过多线程技术在VB5中的应用,为企业级应用,尤其是在远程应用程序及客户机/服务器的分布式处理方面,提供了强大多任务处理能力以及共享网络服务器带来的多用户访问特性。为多任务的大型应用程序提供了一种优化的解决思路和方法。

参考文献
1 美 Stefano Maruzzi 《The Microsoft Windows 95 Developer's Guide》
北京:机械工业出版社 1997.1
2 美 Dan Appleman 著《 Dan Appleman's Visual Basic 5.0 Programmer's Guide to the Win32 API 》 北京:机械工业出版社 1998.8
3 美 Chapman.D 著《Web Development with Visual Basic 5.0》
北京:机械工业出版社 1998.6
4 美 Mckelvy,M等 著《Special Edition Using Visual Basic 5》
北京:机械工业出版社 1997.12


返回主页