LabVIEW多线程编程数据传递教程

描述

很多时候在一个VI的不同线程或者不同VI的不同线程中需要有一些交互——这些线程并不能完全独立运行,需要一定的数据通信才能正确执行,这时就需要在编程时使用LabVIEW提供的数据通信与同步的一些机制,使需要传递的数据可以在多个线程之间流通,这样才能使程序按照正确的预期来执行。

本篇文章小编会跟大家讲解一些常用的数据通信与同步的方法,欢迎大家来一起交流讨论!

本文教程:

LabVIEW多线程编程数据传递

首先我们要知道用户一般是想在两个并行的循环中传递数据,而不是串行执行的循环,那么什么样的循环是串行执行的,什么样的循环是并行执行的呢?

串行执行循环:

循环之间有隧道连线,并且由于这个数据线的串联导致LabVIEW数据流执行两个循环时串联执行,只有当前面的循环执行结束后,后面的循环才会开始执行,这就是串行执行的循环。

LabVIEW

并行执行循环:

循环之间可以同时独立运行,循环之间不存在影响LabVIEW数据流并行执行两个循环的隧道连线。

LabVIEW

图中的两个循环采取了可以打破数据流的“局部变量”来进行数据的通信,这种方式可能会带来竞争的危险,所以一般不推荐大家作为多线程中传递数据的首选方法。接下来小编给大家列举一些多线程之间数据通信常用的方法。

一、队列:

一般来说,当需要在不同线程之间进行通讯或同步的时候首先要考虑的方法绝对是队列,因为队列操作简单高效,队列传递的是地址而不是值,在大量数据传输时有很高的效率且不会占用过多内存开销。

在掌握了队列操作的API之后就可以非常快速地搭建一个多线程之间的数据传输架构,最基础的多线程软件设计模式—生产者消费者模式就是使用队列搭建的,事实上一些耳熟能详的软件架构比如QMH架构、JKI状态机、AF架构等,它们在多线程中传递数据的模块查找到最底层也都是使用队列封装出来的。

下图是LabVIEW自带的设计模板,它就是使用队列搭建的一个简单的生产者消费者架构,使用队列来在两个线程之间传递数据。

LabVIEW

二、通道连线:

从LabVIEW 2016开始新增了可以在并行代码段之间异步传递数据的“数据线”,也称为“通道连线”。LabVIEW提供了多种通道模板(串流、Tag、消息器等),每种模板表示不同的通信协议,可以根据应用程序的通信需求选择模板。

串流只支持单输入单输出,它是缓冲先进先出数据的一对一消息传输(类似于单条队列),Tag虽然可以支持多个写入和读取,但是多个写入方之间会产生竞争,读取方只能读取到最新写入的那个数据,它是单个值数据的N对M消息传输(类似于一个缓冲区大小为1的有损耗队列)。消息器可以支持多个写入方和读取方,它是按先进先出顺序的缓冲命令类消息的N对M消息传输(类似于多条队列并行)。

如需创建通道线,首先应创建写入方端点:右键单击接线端或类型,选择 创建»通道写入方 。从写入方端点的通道接线端绘制通道线并创建读取方端点:右键单击通道线,选择 创建»通道读取方 。

LabVIEW

通道线在代码段之间传输数据的方式与引用句柄或变量相同。但通道线所需的节点数少于引用句柄或变量,并且使用可见的连线直观表示数据传输。

LabVIEW

上图是一个使用通道连线的范例,可以在两个并行循环中传递数值数据,除了数值类型以外,通道连线还可以接受LabVIEW中存在的任何数据类型,例如字符串、枚举、路径、波形、布尔值、簇、数组、对象等。

LabVIEW

注意事项:

1、不要组合使用常规连线和通道连线连接循环;

LabVIEW

2、通道不是数据,不可以放入数据容器中;

LabVIEW

3、通过在写入端点上设置缓冲区大小来限制缓冲区;

4、使用串流通道时,消费者循环的速度必须高于生产者循环,如果生产者循环比消费者循环运行更快,会占用大量内存(未设置缓冲区大小时);

三、功能性全局变量:

相信大家对LabVIEW中的局部变量和全局变量都有一定的了解,它们分别可以在单个VI中或者单个应用程序的所有VI中传递数据。它们使用十分方便,导致很多用户对它们使用十分频繁,可是一旦使用不当,就会产生竞争,进而导致数据错误传递,产生未预期的结果,这种错误很难排查。而使用功能性全局变量可以更加安全地在多个线程之间传递数据。

功能性全局变量其实是一个VI,它既可以实现全局变量的功能又可以避免竞争,所以在某些传递数据的需求中可以用它来代替全局变量使用。一个功能性全局变量必须具备:1、只循环一次的循环;2、未初始化的移位寄存器;3、指定动作输入参数的枚举;4、设置为“非重入VI”。

LabVIEW

如上图所示,这是一个很简单的功能性全局变量,它可以用来在不同调用方中传递一个双精度浮点数据。只循环一次的循环可以让这个功能性全局变量每次被调用只执行一次对应动作,未初始化的移位寄存器可以使全局变量中始终保存上次动作结束后的值而不被初始化掉;指定动作输入参数的枚举可以指定不同调用方执行数据的读取或写入。通常功能性全局变量都会设置为非重入执行,这样可以保证它被调用时始终按照被调用的顺序来执行,从而避免引起竞争。

四、用户事件:

用户事件属于动态事件的一种,它可以在不同的VI中传递一些自定义的数据,所以我们在多线程编程中可以使用它在不同线程中传递数据。小编之前写过一篇给关于动态事件的文章,对这种方法感兴趣的小伙伴可以参考下面的链接学习如何利用用户事件传递数据:

总结:

除了文章中介绍的这四种数据传递方法之外,LabVIEW其实还有很多其他多线程之间的同步机制,比如网络流、通知器、共享变量、信号量等,由于篇幅所限,在这就不过多赘述了,感兴趣的小伙伴欢迎留言讨论!

以上就是有关LabVIEW多线程编程第二章节的所有内容啦,系列文章浅谈LabVIEW多线程编程的内容分享结束,欢迎大家一起交流探讨!
 

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分