APP下载

LabWindows/CVI多线程技术的应用研究

2012-01-15单体强张万发

电子设计工程 2012年15期
关键词:数据保护控件调用

单体强,陈 雷,张万发

(军械工程学院 弹药工程系,河北 石家庄 050003)

随着现代测控系统自动化水平的不断提高,在大型测控系统的软件设计过程中,经常会遇到需要多个任务同时工作的情况。若采用传统的单线程编程方法,软件系统的执行效率低,系统可靠性差;而多线程技术特别适用于实时多任务系统[1],采用多线程技术,则可以把这些任务分配给多个线程同时执行,在一段时间内并行完成多个任务,提高了软件的执行效率和系统可靠性。LabWindows/CVI是NI公司提供的一种ANSI C集成开发环境[2],其将多线程技术引入虚拟仪器软件设计中,有效利用OS和CPU,缩短响应时间、避免拥塞出现,使系统整体性能得到大幅提高。

1 进程与多线程技术

进程通常被定义为应用程序的运行实例。在Win32中,每个进程拥有4 GB的地址空间,此外还有别的资源,如文件、动态内存分配和线程[3]。这些资源在进程中被创建,当进程终止时被释放。

线程是进程内部可独立执行单元,是操作系统对系统资源的基本调度单位。多线程是指操作系统支持一个进程中执行多个线程的能力。应用程序中的每个进程都拥有一个主线程和零到多个次线程。同属于一个进程的线程共享进程的虚拟地址空间,线程之间可共享进程的全局数据和资源。此外,每个线程都单独保存一些数据结构、CPU寄存器指针和堆栈,以保存线程和执行环境。进程与线程之间的资源分布关系如图1所示。

图1 进程与线程之间资源分布关系图Fig.1 Relation chart of thread and process resources

2 LabWindows/CVI多线程技术运行机制

LabWindows/CVI提供两种次线程运行代码的高级机制,分别是线程池 (thread pools)和异步定时器(asynchronous timers)。线程池适用于需要不连续地执行或在循环中执行的任务,而异步定时器适用于在固定时间间隔内执行的任务[4]。

2.1 线程池运行机制

线程在线程池中创建和管理,线程池在主线程中创建。当唤出次线程的控件得到响应时,则在线程池中创建一个次线程,线程函数就通过占用Windows的时间片开始运行,而不再需要程序流程的干预,直到主动或被动停止为止。线程池中对多线程的管理包括创建线程池、创建线程、运行线程函数、释放线程池资源等。

线程池的运行需要调用Utility Library中的Cmt Schedule Thread Pool Function函数,把在次线程中执行的函数名传递给它,使其在线程池的一个次线程中运行。调用Cmt Waitfor Schedule Thread P-ool Function Completion函数使主线程在结束之前处于等待状态,直到线程函数完成执行。如果主线程在次线程完成执行之前退出,则次线程可能没有机会完全释放其占用的资源,次线程中用到的库函数也可能没有机会完全释放。在多线程程序中,调用函数Cmt Release Thread Pool Function ID和函数Cmt Terminate Thread Pool Thread均可退出线程,但是后者无法保证安全退出线程,处理不当有可能导致无法工作。调用函数Cmt New Thread Pool可以创建一个新的线程池,Cmt New Thread Pool会返回线程池的句柄(pool Handle),并把它传递给函数CmtSchedule Thread Pool Function的第一个参数。通过Cmt New Thread Pool创建的线程池,在该线程结束时,必须调用Cmt Discard Thread Pool函数释放该线程池的资源。

2.2 异步定时器运行机制

同步定时器执行线程的优先级比较低[5],当程序线程在别处停滞或响应用户界面操作时,其发送的定时消息会受到消息队列和系统时钟频率等因素的影响,使定时消息得不到及时的响应和处理,这给基于定时功能的重要操作的编程带来极大的不利。异步定时器利用Windows多媒体定时器在指定的时间间隔点调用执行函数,异步定时的时间间隔精确,可对设备进行软件定时。与同步定时器相比,异步定时器使用独立线程,与程序主线程无关,能够提供可靠的定时精度,有效避免了由于程序主线程或用户界面操作而产生的延时,确保了定时器事件的实时性。异步定时器本质上是多线程技术的一种应用形式。

基于LabWindows/CVI,利用同步定时器实现单线程工作模式,如图2所示,利用异步定时器实现多线程工作模式,如图3所示,以此比较两者的软件执行效率和系统可靠性。单线程模式下,在定时器控件的回调函数中产生数据并在第一个绘图控件上绘出曲线。多线程模式下,利用异步时钟产生一个次线程,并在这个线程中产生数据,同时在主线程的定时器控件的回调函数中显示数据。第二个绘图控件用来直观反映定时器控件每次执行代码所需的时间。在单线程工作模式下,若进行其他界面操作,那么显示数据操作被推迟,显示的数据失真,时间间隔大大超过了所界定的200 ms。在多线程工作模式下,因为显示数据和产生数据分属两个不同的线程,所以其它界面操作并未影响数据处理与波形显示产生。这说明多线程在提高软件执行效率和系统可靠性等方面均优于单线程。

图2 单线程工作模式Fig.2 Single threading modle

图3 多线程工作模式Fig.3 Multithreading modle

3 LabWindows/CVI多线程数据保护机制

数据保护是使用多线程技术时必须解决的一个关键问题,保护全局变量、静态局部变量和动态分配的变量,避免它们被多个线程同时访问时造成逻辑错误。 Lab Windows/CVI提供了3种线程同步数据保护机制:线程锁(thread lock)、线程安全变量 (thread safe variables)和线程安全队列(thread safe queues)[6]。线程锁与线程安全变量数据保护机制是线程同步中对资源的互斥使用;线程安全队列数据保护机制是线程同步中两个以上线程基于某个条件来协调它们的活动,一个线程的执行依赖于另一个协作线程的消息或信号,当一个线程没有得到来自另一个线程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

3.1 线程锁数据保护机制

在线程锁数据保护机制中,数据保护是通过将保存数据的变量和OS中的线程锁对象进行关联来实现的。在一个特定的时间内,OS只允许一个线程获得特定的线程锁对象。程序利用CmtNewLock函数建立线程锁;利用CmtGetLock函数使指定线程获得线程锁控制权。每一个时刻只能有一个线程获得线程锁,且每次调用此函数后必须调用CmtReleaseLock函数释放线程锁控制权。若程序中使用的线程占有线程锁较长时间,可能导致其它想获得线程锁的线程不得不等待较长时间,降低了程序的可执行性,容易出现阻塞甚至死锁,效率较低。

3.2 线程安全变量数据保护机制

线程安全变量把数据和OS中的线程锁定对象组合成为一个整体。因为只需要传递线程安全变量句柄,而不是传递线程锁句柄和被保护的变量,所以被保护数据更容易在函数间传递。第一次访问线程安全变量需调用Initialize Var Name函数,在程序中止前调用Uninitialize Var Name函数,调用Cet Pointer To Var Name函数来独占该变量,可以进行线程安全变量的访问。访问结束后,调用Release Pointer To Var Name函数放弃对该变量的占有权,以便其它线程访问该变量。

3.3 线程安全队列数据保护机制

线程安全队列是线程间安全传输数组的一种机制,是为多个线程之间传递大批量数据提供的一种数据保护措施。线程安全队列内部采用了锁策略,有效避免了线程间的冲突、数据错误、死锁等情况的出现。调用Cmt New TSQ函数可以实现线程安全队列的建立。在调用该函数时,根据线程间传送数据信息量多少,指定线程安全队列的项目数和每一项目的大小。写线程调用函数Cmt Write TSQ Data将一定数量的数据信息写入到线程安全队列中,而读线程调用函数Cmt Read TSQ Data从安全队列中读取指定数量的数据信息。

4 LabWindows/CVI多线程技术的应用

某武器系统中所涉及的需进行测控的资源达二十多种。所有测控资源的初始化都是在启动测控程序时完成的,所有测控资源的关闭是在退出程序时完成的。因此,若用单线程初始化/关闭所有的测控资源会导致程序启动/退出时间过长,降低了软件执行效率和系统可靠性。据此,在设计启动/退出程序时,采用了Lab Windows/CVI多线程技术。限于篇幅,只给出测控程序的启动流程图,如图4所示。

程序启动后开始执行主线程,主线程启动两个次线程来初始化仪器。当次线程初始化仪器完毕后,置该次线程的标志变量为1,然后调用函数Set Sleep Policy,使其处于休眠状态。在退出程序时,再启动这两个次线程关闭测控资源。主线程用于处理用户界面事件,若用户界面上的“取消”控件被按下,则应立即终止测控资源的初始化,退出测控程序。如果用单线程编写测控程序,当出现突发故障需立即终止程序执行时,按下“终止”控件,有时会发现程序不能立即响应用户界面事件,可能由此造成严重后果。采用多线程技术可以很好的解决此问题。在“启动”控件按下时,系统创建一个新的线程用于自动测控过程,而主线程用于处理用户界面事件,这样在需要紧急终止测试程序时,可以保证事件响应的实时性。当主线程接到终止命令时,调用Cmt Terminate Thread Pool Thread函数结束次线程函数的执行,并调用函数Cmt Release Thread Pool Function ID释放线程函数资源,提高了测控系统的可靠性。

5 结束语

图4 测控程序启动过程流程图Fig.4 Flow chart of the software startup

深入研究了Lab Windows/CVI多线程技术的运行机制及其数据保护机制,通过分析和实际应用表明,该技术提高了操作系统的执行效率和系统的可靠性,在改善系统实时性和最大程度利用多处理器的性能上具有明显的优势,对测控技术的发展具有重要的作用。

[1]张毅刚.虚拟仪器软件开发环境Labwindows/CVI编程指南[M].北京:机械工业出版社,2002.

[2]陈矫阳,陈楸.基于LabWindows/CVI多线程数据采集的研究[J].科学技术与工程,2008,8(9):2459-2461.CHEN Jiao-yang,CHEN Qiu.Study of multithread data acquiring on the base of LabWindows/CVI[J].Science Technology and Engineering,2008,8(9):2459-2461.

[3]成凤敏,苏小光.多线程技术在虚拟仪器软件开发中的应用[J].中国测试技术,2008,34(2):48-50.CHENG Feng-min,SU Xiao-guang.Application of multithreading in virtual instrument software development[J].China Measurement Technology,2008,34(2):48-50.

[4]杨东升,王高峰.多线程技术在虚拟仪器开发软件LabWindows/CVI中的实现[J].电测与仪表,2005,42(471):39-54.YANG Dong-sheng,WANG Gao-feng.Application of multithreading based on virtual instrument software Lab Windows/CVI[J].Electrical Measurement&Instrumentation,2005,42(471):39-54.

[5]姜守达,吴昌盛,孙震.LabWindows/CVI多线程机制在数据采集中的应用[J].计算机应用,2004,23(8):56-63.JIANG Shou-da,WU Chang-sheng,SUN Zhen.Application of multithreading in data acquisition based on LabWindows/CVI[J].Computer Application,2004,23(8):56-63.

[6]马青亮,周伦彬,鲍芳.LabWindows/CVI多线程机制在虚拟数字存储示波器中的应用[J].中国测试技术,2007,34(1):60-62.MA Qing-liang,ZHOU Lun-bin,BAO Fang.Application of Labwindows/CVI multithreading technology in virtual DSO[J].China Measurement Technology,2007,34(1):60-62.

猜你喜欢

数据保护控件调用
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
关于.net控件数组的探讨
TPP生物药品数据保护条款研究
基于系统调用的恶意软件检测技术研究
欧盟数据保护立法改革之发展趋势分析
欧盟《一般数据保护条例》新规则评析
药品试验数据保护对完善中药品种保护制度的启示
ASP.NET服务器端验证控件的使用
利用RFC技术实现SAP系统接口通信