关于Labwindows的多线程技术

上传人:ji****72 文档编号:37638553 上传时间:2018-04-20 格式:DOCX 页数:23 大小:51.74KB
返回 下载 相关 举报
关于Labwindows的多线程技术_第1页
第1页 / 共23页
关于Labwindows的多线程技术_第2页
第2页 / 共23页
关于Labwindows的多线程技术_第3页
第3页 / 共23页
关于Labwindows的多线程技术_第4页
第4页 / 共23页
关于Labwindows的多线程技术_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《关于Labwindows的多线程技术》由会员分享,可在线阅读,更多相关《关于Labwindows的多线程技术(23页珍藏版)》请在金锄头文库上搜索。

1、多任务、多线程和多处理这些术语经常被交替地使用,但是它们在本质上是不 同的概念。使用多线程技术,应用程序可以把它的任务分配到单独的线程中执 行。在多线程程序中,操作系统让一个线程的代码执行一段时间(被称为时间 片)后,会切换到另外的线程继续运行。暂停某个线程的运行而开始执行另一 个线程的行为被称为线程切换。通常情况下,操作系统进行线程切换的速度非 常快,令用户觉得有多个线程在同时运行一样。 目录目录1. 进行多线程编程的原因 2. 选择合适的操作系统 3. LabWindows/CVI 中的多线程技术简介 4. 在 LabWindows/CVI 的辅助线程中运行代码 5. 保护数据 6. 避免

2、死锁 7. 监视和控制辅助线程 8. 进程和线程优先级 9. 消息处理 10. 使用线程局部变量 11. 在线程局部变量中存储动态分配的数据 12. 在独立线程中运行的回调函数 13. 为线程设定首选的处理器 14. 额外的多线程技术资源进行多线程编程的原因进行多线程编程的原因在程序中使用多线程技术的原因主要有四个。最常见的原因是多个任务进行分 割,这些任务中的一个或多个是对时间要求严格的而且易被其他任务的运行所 干涉。例如,进行数据采集并显示用户界面的程序就很适合使用多线程技术实 现。在这种类型的程序中,数据采集是时间要求严格的任务,它很可能被用户 界面的任务打断。在程序中使用多线程技术的第

3、二个原因是程序中可能需要同时进行低速的输入/ 输出操作。例如,使用仪器来测试电路板的程序将从多线程技术中获得显著的 性能提升。在 LabWindows/CVI 程序中使用单线程技术时,程序员需要从串口发 送数据,初始化电路板。,程序需要等待电路板完成操作之后,再去初始化测 试仪器。必须要等待测试仪器完成初始化之后,再进行测量,。在 LabWindows/CVI 程序中使用多线程技术时,你可以使用另一个线程来初始化测 试仪器。这样,在等待电路板初始化的同时等待仪器初始化。低速的输入/输出 操作同时进行,减少了等待所需要的时间总开销。在程序中使用多线程技术的第三个原因是借助多处理器计算机来提高性能

4、。计 算机上的每个处理器可以都执行一个线程。这样,在单处理器计算机上,操作系统只是使多个线程看起来是同时执行的,而在多处理器计算机上,操作系统 才是真正意义上同时执行多个线程的。例如,进行数据采集、将数据写入磁盘、 分析数据并且在用户界面上显示分析数据,这样的程序很可能通过多线程技术 和多处理器计算机运行得到性能提升。将数据写到磁盘上和分析用于显示的数 据是可以同时执行的任务。在程序中使用多线程技术的第四个原因是在多个环境中同时执行特定的任务。 例如,程序员可以在应用程序中利用多线程技术在测试舱进行并行化测试。使 用单线程技术,应用程序需要动态分配空间来保存每个舱中的测试结果。应用 程序需要手

5、动维护每个记录及其对应的测试舱的关系。而使用多线程技术,应 用程序可以创建独立的线程来处理每个测试舱。然后,应用程序可以使用线程 局部变量为每个线程创建测试结果记录。测试舱与结果记录间的关系是自动维 护的,使应用程序代码得以简化。选择合适的操作系统选择合适的操作系统微软公司的 Windows 9x 系列操作系统不支持多处理器计算机。所以,你必须在 多处理器计算机上运行 Windows Vista/XP/2000/NT 4.0 系统来享受多处理器带 来的好处。而且,即使在单处理器计算机上,多线程程序在 Windows Vista/XP/2000/NT 4.0 上的性能也比在 Windows 9x

6、 上好。这要归功于 Windows Vista/XP/2000/NT 4.0 系统有着更为高效的线程切换技术。但是,这种性能上 的差别在多数多线程程序中体现得并不是十分明显。对于程序开发,特别是编写和调试多线程程序而言,Windows Vista/XP/2000/NT 4.0 系列操作系统比 Windows 9x 系列更为稳定,当运行操 作系统代码的线程被暂停或终止的时候,操作系统的一些部分有可能出于不良 状态中。这种情况使得 Windows 9x 操作系统崩溃的几率远远高于 Windows Vista/XP/2000/NT 4.0 系统的几率。所以,NI 公司推荐用户使用运行 Windows

7、 Vista/XP/2000/NT 4.0 操作系统的计算机来开发多线程程序。LabWindows/CVILabWindows/CVI 中的多线程技术简介中的多线程技术简介NI LabWindows/CVI 软件自二十世纪九十年代中期诞生之日起就支持多线程应 用程序的创建。现在,随着多核 CPU 的广泛普及,用户可以使用 LabWindows/CVI 来充分利用多线程技术的优势。与 Windows SDK threading API(Windows 软件开发工具包线程 API)相比, LabWindows/CVI 的多线程库提供了以下多个性能优化:ThreadThread poolspools

8、 帮助用户将函数调度到独立的线程中执行。Thread pools 处理线程缓存来最小化与创建和销毁线程相关的开销。 Thread-safeThread-safe queuesqueues 对线程间的数据传递进行了抽象。一个线程可以在 另一个线程向队列写入数据的同时,从队列中读取数据。 Thread-safeThread-safe variablesvariables 高效地将临界代码段和任意的数据类型结合在 一起。用户可以调用简单的函数来获取临界代码段,设定变量值,然后 释放临界代码段。 ThreadThread lockslocks 提供了一致的 API 并在必要时自动选择合适的机制来简化

9、临界代码段和互斥量的使用。例如,如果需要在进程间共享互斥锁,或 者线程需要在等待锁的时候处理消息,LabWindows/CVI 会自动使用互斥 量。临界代码段使用在其它场合中,因为它更加高效。 Thread-localThread-local variablesvariables 为每个线程提供变量实例。操作系统对每个进 程可用的线程局部变量的数量进行了限制。LabWindows/CVI 在实现过程 中对线程局部变量进行了加强,程序中的所有线程局部变量只使用一个 进程变量。 可以在 UtilityUtility LibraryMultithreadingLibraryMultithreadin

10、g 下的 LabWindows/CVI 库函数树状图 中找到所有的多线程函数。在在 LabWindows/CVILabWindows/CVI 的辅助线程中运行代码的辅助线程中运行代码单线程程序中的线程被称为主线程。在用户告诉操作系统开始执行特定的程序 时,操作系统将创建主线程。在多线程程序中,除了主线程外,程序还通知操 作系统创建其他的线程。这些线程被称为辅助线程。主线程和辅助线程的主要 区别在于它们开始执行的位置。操作系统从 main 或者 WinMain 函数开始执行主 线程,而由开发人员来指定辅助线程开始执行的位置。在典型的 LabWindows/CVI 多线程程序中,开发者使用主线程来

11、创建、显示和运 行用户界面,而使用辅助线程来进行其它时间要求严格的操作,如数据采集等。 LabWindows/CVI 提供了两种在辅助进程中运行代码的高级机制。这两种机制是 线程池(thread pools)和异步定时器。线程池适合于执行若干次的或者一个 循环内执行的任务。而异步定时器适合于定期进行的任务。使用线程池使用线程池为了使用 LabWindows/CVI 的线程池在辅助线程中执行代码,需要调用 Utility Library 中的 CmtScheduleThreadPoolFunction 函数。将需要在辅助线程中运 行的函数名称传递进来。线程池将这个函数调度到某个线程中执行。根据配

12、置 情况和当前的状态,线程池可能会创建新的线程来执行这个函数、也可能会使 用已存在的空闲进程执行函数或者会等待一个活跃的线程变为空闲然后使用该 线程执行预定的函数。传递给 CmtScheduleThreadPoolFunction 的函数被称为 线程函数。线程池中的线程函数可以选择任意的名称,但是必须遵循以下原型:int CVICALLBACK ThreadFunction (void *functionData);下面的代码显示了如何使用 CmtScheduleThreadPoolFunction 函数在辅助进程 中执行一个数据采集的线程。int CVICALLBACK DataAcqThr

13、eadFunction (void *functionData); int main(int argc, char *argv) int panelHandle;int functionId;if (InitCVIRTE (0, argv, 0) = 0)return -1; /* out of memory */if (panelHandle = LoadPanel(0, “DAQDisplay.uir“, PANEL) datasafeBufPtr-count = val;safeBufPtr-count+;ReleasePointerToSafeBuf(); 检测对检测对 GetPoin

14、terToVarNameGetPointerToVarName 的不匹配调用的不匹配调用可以通过 DefineThreadSafeScalarVar 和 DefineThreadSafeArrayVar 的最后一 个参数(maxGetPointerNestingLevelmaxGetPointerNestingLevel),来指定最大数目的嵌套调用。通常可 以把这个参数设为 0,这样 GetPointerToVarName 在检测到同一线程中对 GetPointerToVarName 的两次连续调用而中间没有对 ReleasePointerToVarName 进行调用时,就会报出一个运行错误。

15、例如,下面的代码在第二次执行的时候 会报出 run-time error 的错误,因为它忘记了调用 ReleasePointerToCount 函 数。 int IncrementCount (void)int *countPtr;countPtr = GetPointerToCount(); /* run-time error on second execution */(*countPtr)+;/* Missing call to ReleasePointerToCount here */return 0; 如果代码中必须对 GetPointerToVarName 进行嵌套调用时,那么可将

16、 maxGetPointerNestingLevelmaxGetPointerNestingLevel 参数设为一个大于零的整数。例如,下面的代码 将 maxGetPointerNestingLevelmaxGetPointerNestingLevel 参数设定为 1,因此它允许对 GetPointerToVarName 进行一级嵌套调用。DefineThreadSafeScalarVar (int, Count, 1); int Count (void) int *countPtr;countPtr = GetPointerToCount();(*countPtr)+;DoSomethingElse(); /* calls GetPointerToCount */ReleasePointerToCount ();return 0; void DoSomethingElse(void) int *countPtr;countPtr = GetPointerToCount(

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号