多线程,多任务和多处理这些术语经常被交替使用,但是他们在本质上不同的概念,多任务指的是操作系统具有在任务间快速切换使得这些任务看起来是在同步执行的能力。在一个抢占式多任务系统中,应用程序可以随时被暂停。使用多线程技术,应用程序可以把它的任务分配到单独的线程中执行。在多线程程序中,操作系统让一个线程的代码执行一段时间后会切换到另外的线程继续运行,暂停某个线程的运行而开始执行另一个线程的行为被称为线程切换。通常情况下,操作系统进行线程切换的速度非常快,令用户觉得有多个线程在同时运行一样。多处理指的是在一台计算机上使用多个处理器。在对称式多处理(SMP)系统中,操作系统自动使用计算机上所有的处理器来执行所有准备运行的线程。借助多处理的能力,多线程应用程序可以同时执行多个线程,在更短时间内完成更多的任务。

1.进行多线程编程的原因

在程序中使用多线程技术的原因主要有四个,最常见的原因是多个任务进分割,这些任务中的一个或多个是对时间要求严格的而且易被其他任务的运行所干涉。例如,进行数据采集并显示用户界面的程序就很适合使用多线程技术实现。在这种类型的程序中,数据采集是时间要求严格的任务,它很可能被用户界面的任务打断。在LabWindows/CVI程序中使用单线程方法时,程序员可能需要从数据采集缓冲区读出数据并将它们显示到用户界面的曲线上,然后处理事件对用户界面进行更新,当用户在界面上进行操作时,线程将继续处理用户界面而不能返回到数据采集任务,这将导致数据采集缓冲区的溢出。而LabWindow/CVI程序中使用多线程技术时,程序员可以将数据采集操作放在一个线程中,而将用户界面处理放在另一个线程中,这样,在用户对界面进行操作时,操作系统将进行线程切换,为数据采集线程提供完成任务所需的时间。

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

在程序中使用多线程技术的第三个原因是借助多处理器计算机来提高性能。计算机上的每个处理器可以都执行一个线程。这样,在单处理器计算机上,操作系统只是使多个线程看起来是同时执行的,而在多处理器计算机上,操作系统才是真正意义上同时执行多个线程的。例如,进行数据采集、将数据写入磁盘、分析数据并且在用户界面上显示分析数据,这样的程序很可能通过多线程技术和多处理器计算机运行得到性能提升。将数据写到磁盘上和分析用于显示的数据是可以同时执行的任务。

在程序中使用多线程技术的第四个原因是在多个环境中同时执行特定的任务。例如,程序员可以在应用程序中利用多线程技术在测试舱进行并行化测试。使用单线程技术,应用程序需要动态分配空间来保存每个舱中的测试结果。应用程序需要手动维护每个记录及其对应的测试舱的关系。而使用多线程技术,应用程序可以创建独立的线程来处理每个测试舱。然后,应用程序可以使用线程局部变量为每个线程创建测试结果记录。测试舱与结果记录间的关系是自动维护的,使应用程序代码得以简化。

2 LabWindows/CVI的多线程技术简介

Thread pools 帮助用户将函数调度到独立的线程中去执行,处理线程缓存来最小化与创建和销毁线程相关的开销

Thread-safe queues 对线程间的数据传递进行了抽象。一个线程可以在另一个线程向队列写入数据的同时,从队列中读取数据

Thread-safe variables 高效地将临界代码段和任意数据类型结合在一起,用户可以调用简单的函数来获取临界代码段,设定变量值,然后释放临界代码段

Thread locks 提供了一致的API并在必要时自动选择合适的机制来简化临界代码和互斥量的使用。例如,如果需要在进程间共享互斥锁,或者线程需要在等待锁的时候处理消息。CVI会自动使用互斥量。

Thread-local variables 为每个线程提供变量实例,操作系统对每个进程可用的线程局部变量的数量进行了限制。CVI在实现过程中对线程局部变量进行了加强,程序中所有的线程局部变量只使用一个进程变量

在LabWindows/CVI的辅助线程中运行代码

单线程程序中的线程被称为主线程。在用户告诉操作系统开始执行特定的程序时,操作系统将创建主线程。在多线程程序中,除了主线程外,程序还通知操作系统创建其他的线程。这些线程被称为辅助线程。主线程和辅助线程的主要区别在于它们开始执行的位置。操作系统从main或者WinMain函数开始执行主线程,而开发人员来指定辅助线程开始执行的位置。

在典型的LabWindows/CVI多线程程序中,开发者使用主线程来创建、显示和运行用户界面,而使用辅助线程来进行其他时间要求严格的操作,如数据采集等。LabWindows/CVI提供了两种在辅助线程中运行代码的高级机制,这两种机制是线程池和异步定时器。线程池适合与执行若干次的或者一个循环内执行的任务。而异步定时器适合于定期进行的任务。

使用线程池

为了使用CVI的线程池在辅助线程中执行代码,需要调用Utility Library中的CmtScheduleThreadPoolFunction函数。将需要在辅助线程中运行的函数名称传递进来。线程池将这个函数调度到某个线程中去执行,根据配置情况和当前的状态,线程池可能会创建新的线程来执行这个函数,也可能会使用已存在的空闲进程执行函数或者会等待一个或者会等待一个活跃的线程变为空闲然后使用该线程执行预定的函数。传递给CmtScheduleThreadPoolFunction的函数被称为线程函数。线程池中的线程函数可以选择任意的名称,但是必须遵循以下原型

int CVICALLBACK ThreadFunction(void *functionData);

下面的代码显示了如何使用CmtScheduleThreadPoolFunction函数在辅组进程中执行一个数据采集的线程

int  CVICALLBACK DataAcqThreadFunction(void *functionData);int main (int argc,char *argv[])
{int panelHandle;int functionId;if(InitCVIRTE (0,argv,0)==0)return -1;if((panelHandle=LoadPanel(0,"DAQDisplay.uir",PANEL))<0)return -1;DisplayPanel(panelHandle);CmtScheduleThreadPoolFunction(DEFAULT_THREAD_POOL_HANDLE,DataAcqThreadFunction,NULL,&functionId);RunUserInterface();DiscardPanel(panelHandle);CmtWaitForThreadPoolFunctionCompletion(DEFAULT_THREAD_POOL_HANDLE,functionId,0);return 0;}int CVICALLBACK DataAcqThreadFunction(void *functionData){while(!quit){Acquire(....);Analyze(....);}return 0;
}

在前面的代码中,主线程调用了CmtScheduleThreadPoolFunction函数,使线程池创建了一个新的线程来运行DataAcqThreadFunction线程函数。主线程从CmtScheduleThreadPoolFunction函数返回,而无须等待DataAcqThreadFunction函数完成。在辅助线程中的DataAcqThreadFunction函数与主线程中的调用是同时执行的。

CmtScheduleThreadPoolFunction函数的第一个参数表示用于进行函数调度的线程池。CVI的Utility Library中包含了内建的默认线程池。传递常数DEFAULT_THREAD_POOL_HANDLE表示用户希望使用默认的线程池。但是用户不能对默认线程池的行为进行自定义。用户可以调用CmtNewThreadPool函数来创建自定义的线程池。CmtNewThreadPool函数返回一个线程池句柄,这个句柄将作为第一个参数传递给CmtScheduleThreadPoolFunction函数。程序员需要调用CmtDiscardThreadPool函数来释放由CmtNewThreadPool函数创建的线程池资源。

CmtScheduleThreadPoolFunction函数中最后一个参数返回一个标识符,用于在后面的函数调用中引用被调度的函数,调用CmtWaitForThreadPoolFunctionCompletion函数使得主线程等待线程池函数结束后再退出。如果主线程在辅助线程完成之前退出,那么可能会造成辅助线程不能正确地清理分配到资源。这些辅助线程使用的库也不会被正确的释放掉。

线程安全队列

使用CVI  Utility Library 的线程安全队列,可以在线程间安全地传递数据。当需要用一个线程来采集数据而用另一个线程来处理数据时,这种技术非常有用。线程安全队列在其内部处理所有的数据锁定。通常来说,应用程序中的辅组线程获取数据,而主线程在数据可用时读取数据然后分析并/或显示数据。下面的代码显示了数据如何使用线程安全队列将数据传递到另一个线程,在数据可用时,主线程利用回调函数来读取数据。

int queue;int panelHandle;int main(int argc, char *argv[])
{if(InitCVIRTE(0,argv,0)==0){if(InitCVIRTE(0,argv,0)==0)return -1;if((panelHandle=LoadPanel(0,"DAQDisplay.uir",PANEL))<0)return  -1;CmtNewTSQ(1000,sizeof(double),OPT_TSQ_DYNAMIC_SIZE,&queue);CmtInstallTSQCallback (queue,EVENT_TSQ_ITEMS_IN_QUEUE,500,QueueReadCallback,0,CmtGetCurrentThreadID(),NULL);CmtScheduleThreadPoolFunction(DEFAULT}}

·

LabWindowCVI中的多线程技术相关推荐

  1. LabWindows™/CVI中的多线程技术

    目录(?)[+] http://zone.ni.com/devzone/cda/tut/p/id/6943#toc3 LabWindows™/CVI中的多线程技术 2 ratings | 2.50 o ...

  2. LabWindows™/CVI中的多线程技术【转】

    http://zone.ni.com/devzone/cda/tut/p/id/6943#toc3 LabWindows™/CVI中的多线程技术 2 ratings | 2.50 out of 5 R ...

  3. qt qthead里如何响应信号_Qt 中的多线程技术(翻译)

    原文链接 Multithreading Technologies in Qt​doc.qt.io 正文 Qt 提供一系列的类与函数来处理多线程.Qt 开发者们可以使用下面四种方法来实现多线程应用. Q ...

  4. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  5. 在WPF程序中使用多线程技术

    在WPF应用程序中使用多线程的方式与Windows Forms很类似,区别在于,如果需要更新主线程UI上面的元素,需要用一个特殊的方法(this.Dispatcher.Invoke) 下面是一个简单的 ...

  6. iOS 多线程技术总结

    概览 进程与线程的概念 多线程的由来 并行与并发 多线程的实现 串行与并行 线程的几种状态 串行队列与并发队列区别 iOS 实现多线程的几种方法(NSOperation/GCD) GCD线程阻塞的几种 ...

  7. HTML5中Web Worker技术的使用实例

    web worker是html5中新特性中非常吸引人的技术亮点之一,我们可以把它理解为javascript中的多线程技术,我们知道javascript语言的执行环境是单线程的,浏览器执行某段程序的时候 ...

  8. 多线程技术和多核技术

    为什么 Intel 的超线程技术是一个核两条线程,而不是更多? 可以说是最优的.CPU在执行单线程任务时,并不是核心内每一个单元都在工作.而超线程技术就是让闲着的那些执行单元去做另一个线程的工作.这时 ...

  9. Android 开发中的多线程编程技术

    此文章来自"Intel Software"应用开发 多线程这个令人生畏的"洪水猛兽",很多人谈起多线程都心存畏惧.在Android开发过程中,多线程真的很难吗? ...

最新文章

  1. Redlock:Redis分布式锁的实现
  2. 2015-12-18 学习心得
  3. 信息抽取新SOTA!首个结构化生成式信息抽取预训练模型,一统信息抽取四大任务...
  4. 西安电子科技大学第16届程序设计竞赛G题
  5. Android风格ppt,Material Design风格的快手PPT
  6. ZK实际应用:样式和布局
  7. oracle mseq,一次RMAN备份报错的诊断过程(一)
  8. 【数字信号处理】基于matlab GUI正选信号时域+频域分析【含Matlab源码 887期】
  9. Robotium在输入框输入文字
  10. 抽奖系统概率设计_《微博抽奖玄学理论·养号攻略XI》
  11. 博图v15编程手册_好消息!全套西门子plc编程软件,案例和说明书下载
  12. WIN10下速腾聚创RS-Ruby lite80线激光雷达ip地址和端口号port修改
  13. uni-app教程支付php,uni-app IOS app微支付、支付宝整合记录
  14. MATLAB直方图均衡化函数的计算及使用
  15. ADIS16488与单片机SPI通信返回0xFFFF的问题解决方法
  16. 鲁大师升级“Pro”,2B领域谋篇布局
  17. 爬虫之scrapy框架的数据持久化存储/保存为scv,json文件
  18. uni-app 启动广告页
  19. python读取合并单元格并拆分合并单元格写出
  20. 极部落TrueChain公链训练营_长沙站[湘链技术社区]

热门文章

  1. 新手小白做自媒体短视频,千万不要做低级剪辑,这点很重要
  2. 100亿美元!美高梅将在大阪开发世界级综合度假目的地;复星时尚集团更名为复朗集团 | 美通社头条...
  3. 我10年来的学习和生活――应聘成功后的总结
  4. javascript跳转到新页面的三种方法
  5. FPGA篇 ila使用例子
  6. 2020高人气小巧真无线蓝牙耳机推荐,无线蓝牙耳机选购指南
  7. 高通助力Libratone小鸟音响新一代真无线耳机发布
  8. 失信企业查询_在不丢失信标的情况下找到信标:我进入Android低功耗蓝牙领域的旅程...
  9. 逻辑回归算法处理简单数据
  10. $.get()的使用