多线程技术在校园“一卡通”系统中的应用
文章出处:http://www.nexussmartsolutions.com 作者: 人气: 发表时间:2011年09月09日
⒈ 引言
校园“一卡通”系统为“数字化校园”提供了全面的数据采集网络平台,是“数字化校园”建设的重要组成部分和基础工程。所谓“一卡通”,即在学校内,凡有现金、票证或需要识别身份的地方均采用卡来完成,它既是数字校园的数据信息存储和处理中心,也是整个数字校园的核心引擎,是一个跨平台、跨数据库的可自我发展的数字化校园信息系统平台,既可为学校已有的各管理系统建立接口,连接各个管理子系统,又可实现整个数字校园的数据无重复、无冗余的存储与共享,真正实现“一卡在手,走遍校园”。
在校园“一卡通”系统中引入Delphi提供的多线程技术,使得系统程序结构更加合理,避免了程序运行时单一线程瓶颈所造成的系统资源的极大浪费,最大限度地提高了系统资源的存储及共享效率。
⒉ 多线程编程
2.1 线程概述
线程(Thread)是个动态的对象,它是处理器调度的基本单位,表示进程中的一个控制点,执行一系列的指令。在操作系统中引入线程的概念,可减小并发执行的时间和空间开销,允许通过在系统中建立更多更好的线程来提高并发性。
2.2 多线程编程技术
所有进程至少都拥有一个执行线程,我们称该执行线程为主线程。在一个程序中,除了主线程之外,可能还创建有一个或更多的执行线程。通常,一个线程一旦创建即开始执行。
2.3 线程类的特性及方法
线程类包括FreeOnTerminate、Thandle、Priority、ReturnValue、 Suspended、Terminated、ThreadID等特性。
线程类主要包括DoTerminate过程、Execute过程、Resume过程、Suspend过程、Synchronize过程、Terminate过程等几种方法。
⒊ 多线程编程在“一卡通”系统中的应用
在“一卡通”系统中有四个线程共同使用平台服务器的资源一起工作,即:平台服务器主线程、子系统流水处理线程、中间件接收子系统流水线程、中间件转发收到的流水线程。
3.1 多线程技术在平台服务器中的应用
当整个一卡通系统运作起来时,平台服务器、中间件、接收流水线程同时运行,平台服务器完成统计和查询的任务,中间件实现与各个子系统之间数据的通信,接收子系统处理的数据并下发给其它子系统,接收流水的线程完成对各个子系统的数据处理,提交到中心数据服务器。
中间件接收子系统的流水,接收到后就转发到其它子系统。子系统上传来流水的处理,是通过流水处理线程单独完成的。平台服务器主程序不参与流水的处理,只上传处理后的数据进行统计和查询。子系统随时有流水产生就随时发送,中间件随时接收,处理线程随时处理,主程序就能随时查询到卡的消费情况。四个线程一起工作,保证整个“一卡通”的实时性、高效性。
3.2 多线程技术在子系统中的应用
在各个子系统的服务器中,同样运行着子系统服务器线程、中间件发送线程、中间件接收线程和接收流水处理线程等四个线程。四个线程同时运行保证子系统与服务器数据同步。子系统产生流水,中间件发送,中间件接收平台服务器发出的流水,处理线程对接收到的流水进行处理。多线程运行原理与平台服务器是一样的,实现方式略有不同。平台服务器对上传来的流水保存流水记录,并修改帐户余额,而在子系统中不保存流水记录,只修改帐户余额。
3.3 中间件的主要线程
中间(middleware)件是位于平台(硬件和操作系统)和应用之间的通用服务,这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台,它们可以有符合接口和协议规范的多种实现。
在中间件服务器端静态放置一个ServerSocet组件,用于提供动态分配客户连接端口的代理服务。客户端向服务器请求链接时,客户端向服务器发请求连接。服务器端响应OnConn及OnAccept事件。客户端连接服务器成功后,向服务器端发送分配新端口指令。服务器端在客户机连接映射表中搜索此客户机,有返回已分配的端口号,无分配一新的端口号。端口分配成功后,动态创建两个ServerSocet组件,一个用于发送数据,一个用于接收数据。
线程主要语句如下:
Socket.ReceiveBuf(S_Buf, Socket.ReceiveLength); //取缓冲区数据
S_Num := CalculateCRC(S_Buf, Socket.ReceiveLength - 4);
if not ((S_NumBuf[0]=S_Buf[S_ReceiveLen-4])and
(S_NumBuf[1]=S_Buf[S_ReceiveLen-3])and (S_NumBuf[2]=S_Buf[S_ReceiveLen-2])and
(S_NumBuf[3]=S_Buf[S_ReceiveLen-1] )) then
begin //CRC校验错误,退出
exit;
end;
if copy(S_Buf, 0, 5) = ‘00000’then
begin
S_ZIPCode := Trim(copy(S_Buf, 6, 5)); //工作站编码
S_Host := Trim(copy(S_Buf, 11, 20)); //机器名称
S_Addr := Trim(copy(S_Buf, 31, 15)); //IP地址
//查询此客户机器是否连接过服务器
S_ClientNO := G_ClientHostList.IndexOf(S_ZIPCode);
if S_ClientNO >= 0 then
begin
//找到,给客户返回端口号码等信息
S_Str := AddLeftZero(IntToStr(G_ServerSocketInfo[S_ClientNO].ServerUp.Port),5);
//客户上传端口
S_Str:=S_Str+AddLeftZero(IntToStr(G_ServerSocketInfo [S_ClientNO].ServerDown.Port), 5);
//下传端口
OnSendBackClient(10033, ‘00001’, S_Str, Socket);
End;
Try
S_ClientNO := G_ClientHostList.Add(S_ZIPCode);
G_ServerSocketInfo[S_ClientNO].ServerDown :=
TServerSocket.Create(nil);
G_ServerSocketInfo[S_ClientNO].ServerUp :=
TServerSocket.Create(nil);
//客户上传端口
S_ClientPort := GetNewPort;
G_ServerSocketInfo[S_ClientNO].ServerUp.Port := S_ClientPort
//下传端口
S_ClientPort := GetNewPort;
G_ServerSocketInfo[S_ClientNO].ServerDown.Port :=
S_ClientPort;
//开始监听
G_ServerSocketInfo[S_ClientNO].ServerUp.Active := true;
G_ServerSocketInfo[S_ClientNO].ServerDown.Active := True;
except
OnSendBackClient(10038, ‘00002’, ‘90001’, Socket);
//服务器分配端口失败
end;
OnSendBackClient(100033, ‘00001’, S_Str, Socket);
//服务器分配端口成功
End;
3.4 多线程技术实现的难点
虽然多线程可以提高系统效率,但存在很大的危险性。在程序编写时一定要注意在多线程环境下运行可能会出现的情况:
(1) 当对某一帐户进行把余额赋值成某个值的补贴操作时,其它子系统也有对这个帐户的余额操作时,就会出现帐目上的不平衡。解决这个问题的办法就是对余额的操作只能对加减不能直接赋值,这样就避免了这个问题的出现。
(2) 当接收到流水和本地要同时对某个帐户进行操作时,就会出现数据库中帐户余额表的某条记录被锁的情况。在接收流水的处理线程中,若一次处理不成功,可多处理几次,等待本地释放被锁记录。
⒋ 结束语
在“一卡通”系统中采用多线程编程技术,可以提高数据处理的速度,充分利用系统资源,有效提高整个“一卡通”系统的效率,实现整个数字校园的数据无重复、无冗余的存储与共享,真正实现高度数据共享的数字化校园系统。
参考文献:
[1] 王学敏.基于数字化校园的一卡通系统的设计与实现[D].厦门大学学报,2008.
[2] 张升平.数字化校园之校园一卡通的建设[J].重庆工商大学学报,2008,01.
收稿日期:2010-03-03
作者简介:王玲(1965-),女,辽宁鞍山人,鞍山市第三中等职业技术专业学校高级讲师。研究方向:计算机网络。沈霞(1966-),女,辽宁鞍山人,辽宁科技大学计算机科学与工程学院副教授。研究方向:计算机网络。