毕业设计 基于多平台的通用线程库设计教材Word文件下载.docx
- 文档编号:19253683
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:34
- 大小:194.55KB
毕业设计 基于多平台的通用线程库设计教材Word文件下载.docx
《毕业设计 基于多平台的通用线程库设计教材Word文件下载.docx》由会员分享,可在线阅读,更多相关《毕业设计 基于多平台的通用线程库设计教材Word文件下载.docx(34页珍藏版)》请在冰豆网上搜索。
2.2.1例子1:
Boost线程库7
2.2.2例子2:
ZThreads线程库8
2.2.3预处理技术的比较9
2.2独立的开发分支10
2.3设计模式11
2.3.1桥接模式12
2.3.2抽象工厂模式13
第3章跨平台库的设计15
3.1介绍15
3.2核心和路由概述15
3.3应用范例17
第4章跨平台线程库的设计和实现20
4.1线程跨平台的基础20
4.2总体框架设计21
4.3线程库结构化实现23
第5章总结与展望28
5.1总结28
5.1展望28
致谢29
参考文献30
第一章引言
1.1研究背景
1991年Linux出现。
短短10多年,Linux已经迅速发展成为一个至关重要的操作系统。
目前Linux技术[1]已成为国内外信息产业界研究开发的热点。
基于Linux的软件产品已经基本覆盖了计算机软件的各种门类。
但与Windows相比。
用户可供选择的优秀系统软件数量还不太多。
如何利用已有的Windows下的软件资源,迅速的开发出Linux下优秀的应用软件,缩短软件开发周期,已经成为一个热点。
将Windows软件向Linux软件移植将是一个很好的选择,因此如果可以拥有更多的跨平台的库去丰富代码,那么移植也会变得非常轻松。
大部分电脑语言从绝对意义而言,都是跨平台的:
因为都是以高级的、人类可读的方式来对CPU发号指令,这样也就没必要依赖于任何作业系统。
但如果要用系统的部件工具箱,来新建用户图形界面(GUI),就可能会用到开发员特定系统中的API函数或库类。
虽然C++是跨平台的,但Windows下用到Win32API的C++程序,一般就不能在Unix机器上编译。
不同编译器对语言规范的解释也有所差异。
这样的话,在针对不同系统进行构建之前,程序就得加以考虑。
一些如Java这样的语言,从一开始就意识到要在各个平台下运行,所以跨平台在其平台的本地语言环境中已经实现。
例如,Java可以跨平台使用,正是由于Swing库在许多平台下的实现。
类似的,能进行跨平台的文件存取,是因为有各自平台下文件存取的库。
以此类推,各种跨平台问题,都需要各自的本地库来解决。
wxWidgets框架就是这样的一个跨平台库,根据不同的跨平台问题,提供了许多不同的解决方案;
类似的库有许多,可以根据不同语言的跨平台开发,而采用相应的库。
那些解释型语言,或者需要虚拟机的语言,也更加符合跨平台的要求,因为用户也要自己进行编译。
Sun公司的Java虚拟机Hotspot,只针对几种而不是全部平台,提供编译好的二进位文件。
例如,Sun对于GNU/Linux,只支持i386平台,但如果谁在PowerPC或者SPARC电脑上运行Linux,就只好自己编译本地的机器码(machinecode),或者使用第三方软件,才能运行Java程序。
许多API(应用程序介面)依赖于平台。
OpenGL可以看作是跨平台的,因为其不依赖于任何特定的作业系统、CPU构架或者某个牌子的图形设备。
特定平台的API可以在其他系统上作为兼容层而新建,例如WINE的库,Windows程序就可以在UNIX系统上运行。
另外许多程序语言还有跨平台的扩展以及中间件,这样程序设计师对于同样的原始码,只要进行一点小修改,就可以在不同平台下编译/运行,例如Qt和wxWidgets。
1.2主要研究内容
通过学习和研究多种开源库的跨平台技术,并通过对实现方法的总结,而通过运用被称作核心和路由的技术,来实现一种跨平台的线程库,并给出相应实现,最后配上相应的演示功能程序。
1.3论文结构
本文划分为六章,文章的安排结构如下:
第一章简单介绍了跨平台开发库的历史背景,并指出了其在软件开发的重要意义。
第二章介绍跨平台开发的开发环境及几种流行的开发库。
第三章跨平台开发库的框架设计。
第四章跨平台线程库的设计与实现。
第五章总结了关于跨平台库的几点重要特性,并指明了下一步改进计划。
第2章跨平台软件开发环境
本章讨论了常见的跨平台软件开发方法。
开始小节讨论的历史和跨平台的开发方法给出了一个简单的发展,第2小节讨论了跨平台软件开发的第一种方法:
在编译时大量使用预处理器剥离源代码,而在第3小节讨论了跨平台软件开发的第二种方法:
使用不同的开发分支为每个目标平台。
第4小节提出了分类比较这篇论文的软件包,而最后小节简要介绍对于跨平台软件开发中所需要的设计模式及其意义。
2.1跨平台开发的历史
也许最好的方式理解什么是跨平台开发技术以及研究它们起源。
对于很大一部分早期的UNIX发展的,从大约1969年到1976年不等,有没有这样的东西作为跨平台的软件。
一个非常具体的硬件/软件平台编写的软件。
如果平台绝种了,整个包会被移植到老平台的继任者。
一旦多种硬件和软件平台的进一步普及,UNIX内核需要一种方法来编译和运行在许多不同的平台上。
随着程序和Makefile文件[2]在1979年,预处理器被广泛应用在寻求在多个平台上编译的应用程序。
原来的makefile不仅智能编译源文件,也可以将命令行参数传递给编译器。
传递的参数大部分预处理器已经被定义。
随着时间的推移,更多的软件包针对多个平台,最终,独立的开发分支,每个平台的想法来的。
源文件包含对每个平台的代码,而是将分成分支机构发展。
每个分支只包含为特定的平台所需的源代码,从而减少了由预处理器条件检查。
2.2预处理器使用
在第一个跨平台的软件开发方法[3],源文件遍布预处理语句,这使得代码难以阅读,容易出错,很难在所有平台上进行测试,并难以维持。
软件包依赖于这种方法的例子是Boost,ZThreads。
此外,可能读者会注意的POSIX线程包采用提到的方法,但本篇论文认为,“单独的分支”类别更适合它。
一个有趣的现象是,尽管所有这些包预处理大量使用,但他们使用它的方式不同,下面介绍在各自的小节。
然而,即使采用四种不同的方法,使用预处理器,但并没有很好的可读性,代码的安全性也未达成。
每个包所采用的方法是最有可能使用,因为每个包已经习惯了各自的作者说的方法。
这个论文并没有办法旨在宣布优于任何其他这些软件包之一,只是在于观察每个方法的安全性和可读性。
Boost线程库
Boost是—个c++程序库开发的社区和平台,这个组织开发出的程序库被统称为Boost程序库[4],由于其很多成员在c++的标准化组织具有很高地位,因此Boost库被称为“准标准”程序库,在c++爱好者中影响非常广泛。
其许多程序库被广为使用。
相对于操作系统提供的API函数来创建多线程程序而言,Boost线程库是使用到了许多的c++特性,例如构造函数和析构函数、函数对象、模板等等,都可以在其中使用,使其接口更加灵活。
现在的版本已经可以在POSIX、Win32和MacintoshCarbon平台下工作。
而且相对于c++其它方式的编程,其学习成本更低,而且配合使用Bost库中的其它类库,比如智能指库和Bind库,能大大减少编程量,更易编出高质量的c++多线程程序。
Boost的实现可能是最难读懂预处理的方法。
Boost使用预处理器部分,出特定于平台的功能实现而且会去识别各种版本的编译器。
Boost还采用了预处理有条件地确定哪些变量要存储在类中。
这种做法是非常危险的,因为使用者可能预期一定的预处理条件是真实的时候,而实际不是这样,使得类的定义理解错误,并可能导致不明情况的运行错误,下面简要分析一下Boost的thread跨平台处理。
classBOOST_THREAD_DECLthread
{
public:
typedefthread_attributesattributes;
BOOST_THREAD_MOVABLE_ONLY(thread)
private:
structdummy;
voidrelease_handle();
detail:
:
thread_data_ptrthread_info;
private:
boolstart_thread_noexcept();
boolstart_thread_noexcept(constattributes&
attr);
...sourcecodeishere
};
图2.1摘自Boost源代码(Thread.hpp)
pthreadthreadclass实现
win32threadclass实现
图2.2Boost平台识别
正如上面的图解,Boost在实现线程库时通过延迟类的实现,来实现线程库,platform.hpp文件包含了大量的关于系统和编译器的宏,可以正确的识别当前的环境,然后再进行线程类的实现,对于调用者来讲,只需关注thread类的定义,不管在任何系统下,使用的规则不变,这样跨平台的效果就达到了。
ZThreads线程库
ZThreads是一个用C++编写的跨平台的线程API。
使用预处理语句内包含正常条件定义和执行的语句。
在一些地方,它并没有直接用预处理语句区的剥离可执行代码,ZThreads反而会包含特定于平台的实现源代码。
这有助于代码的效率,但仍然使得跟踪源文件的一个问题,因为它可以很难确定哪些文件是通不过的,而这种方式也正是无法达到两全其美的状态,大多数的ZThreads代码是在写入这种方式。
下面显示了ZThreads有条件地定义实现文件包括的一个例子。
#ifdefined(ZT_POSIX)
#include"
posix/ThreadOps.h"
#defineZT_THREADOPS_IMPLEMENTATION\"
posix/ThreadOps.cxx"
#elifdefined(ZT_WIN32)||defined(ZT_WIN9X)
...moresourcecodehere
win32/ThreadOps.h"
#defineZT_THREADOPS_IMPLEMENTATION\
"
win32/ThreadOps.cxx"
#elifdefined(ZT_MACOS)
macos/ThreadOps.h"
#defineZT_THREADOPS_IMPLEMENTATION"
macos/ThreadOps.cxx"
#endif
图2.3摘自ZThreads源代码(ThreadOpts.h)
2.2.3预处理技术的比较
当然还有一些其他的比较优秀的库,也使用了预处理技术去实现跨平台,在此就没有详细介绍,在这里就概括性的给出其中的比较性。
不过从其中也可以看出各自的优劣性。
就像MsgConnect可能本身是给Windows设计的库,但是为了也希望Linux可以调用,又不想改写接口,于是就直接将Linux的接口封装为Windows的标准接口,这样就是进行平台仿真。
利用预处理器技术的跨平台比较
BoostThreads
HawkNL
MsgConnect
ZThreads
条件编译函数
X
可变化的结构成员
条件编译源文件
进行平台仿真
图2.4跨平台技术比较
2.2独立的开发分支
跨平台软件开发的第二种方法归类为具有源代码分割成单独的开发分支。
有点相似的是,Java以语言角度算是不错的语言,语法干净简洁,OO支持也算完整,Framework设计的也不错,写出来的程序语法也蛮漂亮的,还OpenSource,且支持应用很广,从GUI、Component、Web、Embedded都有支持,但Java技术最大的致命伤就是执行速度缓慢,透过VirtualMachine技术使得Java得以实现跨平台,什么是VirtualMachine呢?
简单的说,就是在给个OS上在装一个JavaOS跑Java程序,这种方式就像你写了一个Windows程序,然后也宣称是跨平台,只要User在Linux或Mac装上VMWare,然后在VMWare下灌WindowsXP,这样也能在Linux、Mac下执行你的Windows程序,但经验告诉我们,用VMWare跑其它OS,速度大约只剩下6成左右而已,Java程序速度慢的原因就在这里,这是VirtualMachine的宿命。
而单独的开发分支不是虚拟机,而是实实在在的底层接口的封装,现在这一类的包是相当大的,继续保持积极发展的状态。
使用单独的开发分支项OpenSG,QT,GTK和POSIX线程。
所有这些项目仍处于积极开发和细化中,他们都支持多种平台。
例如,OpenSG支持4作业系统(Windows,VanillaLinux,Irix,和Irix64),一共有5个编译器(英特尔的编译器,微软的优化编译器为ISOC++,GCC3.2及以上,SGICC,和SGI64位CC)。
一些不可忽略的副作用却会因为包被分成多个开发分支而产生。
首先,最小化的代码共享。
有时访问平台特定的对象和功能,从而使其更难编写独立于平台的代码。
但是最严重的副作用在于发展情况下一个小的设计变更或增强时,而这种改变,需要不同程度的努力将其移植到许多不同的平台上。
在有些封装中中,一个应用程序员可能会因为某项特殊发功能需要,而打破的write-once/compile-anywhere的的模型。
QT允许在某些情况下,从基类的到所有Qt的窗口小工具可以进行扩展以适应特定平台需要,QWidget的代码摘录,如图所示。
自QWidget的以来类给出了到特定于平台的功能的访问,而可能一些程序员可能会喜欢上这种方式,以实现特定于平台的功能。
#ifndefQWIDGET_H
#defineQWIDGET_H
classQ_EXPORTQWidget:
publicQObject,publicQPaintDevice
...moresourceishere
public:
QWidget(QWidget*parent=0,constchar*name=0,WFlagsf=0);
~QWidget();
WIdwinId()const;
voidsetName(constchar*name);
#ifdefined(Q_WS_MAC)
virtualboolmacEvent(MSG*);
#ifdefined(Q_WS_WIN)
virtualboolwinEvent(MSG*);
#ifdefined(Q_WS_X11)
virtualboolx11Event(XEvent*);
#ifdefined(Q_WS_QWS)
virtualboolqwsEvent(QWSEvent*);
virtualunsignedchar*scanLine(int)const;
virtualintbytesPerLine()const;
图2.5Qt平台拓展代码
Qt拥有一个单一的Library,让你开发各种不同平台的程序,目前支持Windows、Linux、Mac、UNIX、EmbeddedLinux,讲白话点,就是它提供了一个Library让你开发GUI程序,写好之后,只要在各平台重新Compile后,就可以在各平台执行,而且使用完整的ANSIC++语言,且不限Compiler,只要是C++的Compiler都可以,重要的是,该Library相当漂亮,写出来的程序很像C++Builder或.NETFramework的那样精简,不会向MFC那样复杂。
然而库从发展的角度来看,管理多个分支机构,可以是一个艰巨的任务。
一个小变化(简单的加法或减法的一个成员函数)的分支可能煽动整个代码,而重新写另一个分支。
这迫使API和库设计师有一个复杂的知识,必须面对的问题就是如何实现各分支,使一个开发分支提出变更时,不会突然落在后面所有的其他分支。
2.3设计模式
设计模式[5]是真实世界的编程解决方案的代表。
设计模式开始出现在20世纪70年代中后期出版工作,更普遍的东西,只是一个更好的方式来实现想法规划,建设,架构和代表性。
设计模式允许程序员可以轻松地分享他们的程序的体系结构,可以分成三大类:
•创建模式
创建型模式抽象了实例化过程。
他们帮助一个系统独立于如何创建、组合和表示他的那些对象。
一个类创建型模式使用继承改变被实例化的类。
而一个对象创建型模式将实例化委托给另一个对象。
•结构模式
结构型模式涉及到如何组合类和对象以获得更大的结构。
结构型模式采用继承机制来组合接口或实现。
因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。
•行为模式
行为模式涉及到算法和对象间职责的分配。
行为模式不仅描述对象和类的模式,还描述它们之间的通信模式。
这些模式刻画了在运行时难以跟踪的复杂的控制流。
他们将你的注意力从控制流转移到对象间的联系方式上来。
本文在实现跨平台线程库是将会依赖于造物的模式和结构模式,提供一个跨平台开发API的更优雅的方式。
具体的使用的设计模式是桥接和抽象工厂。
所以在此详细介绍一下这两种设计模式。
2.3.1桥接模式
定义:
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
类型:
行为类模式
类图:
图2.6桥接模式UML图
为了达到让抽象部分和实现部分都可以独立变化的目的,在桥接模式中,是把抽象部分和实现部分分离开来的,虽然从程序结构上是分开了,但是在抽象部分实现的时候,还是需要使用具体的实现的,这可怎么办呢?
抽象部分如何才能调用到具体实现部分的功能呢?
很简单,搭个桥不就可以了,搭个桥,让抽象部分通过这个桥就可以调用到实现部分的功能了,因此需要桥接。
桥接模式的优点
适当地使用桥接模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
使用桥接模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
使用桥接模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
适用场景
在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。
一个类同时依赖多个类的情况也相当普遍,既然存在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 毕业设计 基于多平台的通用线程库设计教材 基于 平台 通用 线程 设计 教材