关于面向对象的方法并行执行的问题

· 浏览次数 : 13

小编点评

在LabVIEW中,通过调整方法的共享副本可重入属性,可以实现从同一个类实例化的多个对象并行执行各自的方法。默认情况下,类的方法是串行执行的。要实现并行执行,你需要在方法vi中将可重入属性设置为“共享副本可重入”或“预分配克隆可重入”。 在下面的示例中,我们首先创建了一个名为Person的类,该类包含一个描述其状态的私有数据State,一个读写状态的方法ReadState,和一个耗时的方法WalkAWay。我们通过Main.vi来测试这个类的行为。 首先,我们观察默认情况下的执行结果:两个对象的Walk方法执行时间之和为3500ms,说明方法是串行执行的。 接下来,我们修改WalkAWay方法,使其耗时更长,然后再次运行Main.vi进行测试。这次,我们发现执行时间缩短到了2000ms,这是因为WalkAWay方法现在是在各个对象间并行执行的。 通过上述实验,我们可以得出结论:通过调整方法的共享副本可重入属性,我们可以实现从同一个类实例化的多个对象并行执行各自的方法。这种方法尤其适用于多slot并行测试的软件设计,可以大大节约程序执行时间。 需要注意的是,虽然LabVIEW允许我们为方法设置可重入属性,但并不是所有的VI都支持这种设置。例如,如果VI中使用了全局变量或功能全局变量,那么就不能将方法设置为可重入。此外,还需要根据具体的应用场景和原则来选择合适的可重入方式。

正文

LabVIEW的从同一个类实例化的多个对象如何执行各自的方法呢?

这几天跟同事讨论到LabVIEW的面向对象编程中,如果我设计的一个类有一个方法比较耗时,那么当我实例化多个对象时,那么这个耗时的方法是怎么执行的呢?是各自并行执行还是,必须等某一个对象的方法调用完,接下来调用第二个对象的该方法呢?

接下来,我们直接来做个试验吧!

试验设计:

我们设计一个类——Person

该类包含的一个描述其状态的私有数据——State;

有对该数据的读写的接口;

有一个耗时的方法——WalkAWay

好了,类的程序设计完了,我们做一个Main.vi来进行测试:

我们看下执行的结果:

该Main程序共计耗时为2个对象的Walk方法执行时间之和:2000+1500=3500ms;

由此,我们可以看到,默认设计的类,其方法在各个对象间是串行执行的;

接下来,重点:

我们回去修改下我们设计的类的WalkAWay方法。

然后再执行Main测试vi,执行结果:

该Main程序共计执行时间为最长按个WalkAWay方法执行的时间:2000ms.我们可以看到,这次就是并行执行了WalkAWay方法了。

至此,我们可以得出结论:

默认设计的类的方法是串行执行的。那么,如果有耗时的程序,我们可以通过调整方法的共享副本可重入属性来实现不同对象间调用方法并行执行。这个能大大节约程序执行时间,尤其是我们在多slot并行测试的软件设计时尤为重要。

说明:上述如果将方法vi的设置为第三个——预分配副本的话,类的设计会直接报错,也就是说LabVIEW不让我们这么设置。

附件:vi的可重入属性的说明:

Non-reentrant execution
不可重入: 多个调用者调用此VI时,是按照顺序逐一调用的。优势是最小的内存消耗,同时也会使得所有调用该VI的共享一个状态,在调用中保留控件和未被初始化移位寄存器的值。

Shared clone reentrant execution
可重入:在实例间共享副本(减少内存使用),允许多个调用者同步并行执行该VI,这个类型的可重入,为了减少内存消耗,在调用中复用克隆副本。

当调用者B调用该VI时,如果克隆实例正在被调用者A使用中,那么LabVIEW 会分配一个新的克隆实例给调用者B。

当调用者B调用该VI时,如果克隆实例没有被使用,那么LabVIEW不会再开辟新的克隆实例。因此每个调用者维护自己的状态,保留控件和未赋值移位寄存器的值

Preallocated clone reentrant execution
可重入:为各个实例预分配副本,允许多个调用者同步并行执行该VI,这个类型的可重入,为每一个实例预分配独立克隆实例,并以开辟更多的克隆实例为代价。

那么VI何时使用可重入,并且到底选共享副本还是各个实例预分配副本?

场景和原则

  1. 当VI中有使用全局变量、或者功能全局变量时,不能设置成---->可重入:在实例间共享副本(减少内存使用)

  2. 如读取文件一类时,可以考虑设置可重入,使得调用者可以并行执行,提高效率。

  3. 当需要实现一些,共享克隆实例时,可以考虑使用--->可重入:在实例间共享副本(减少内存使用) 例如 递归操作。

  4. 如果VI克隆实例暂用资源很小,但是运行时间较长,可以考虑使用---->可重入:为各个实例预分配副本

  5. VI可重入设置,是为多线程调用准备的,如果在该VI被调用过程中,不会出现多线程调用该VI,那么没有必要设置可重入,保持默认即可。
    引用自:https://www.cnblogs.com/YourDirection/p/12833877.html

与关于面向对象的方法并行执行的问题相似的内容:

关于面向对象的方法并行执行的问题

LabVIEW的从同一个类实例化的多个对象如何执行各自的方法呢? 这几天跟同事讨论到LabVIEW的面向对象编程中,如果我设计的一个类有一个方法比较耗时,那么当我实例化多个对象时,那么这个耗时的方法是怎么执行的呢?是各自并行执行还是,必须等某一个对象的方法调用完,接下来调用第二个对象的该方法呢? 接

【numpy基础】--聚合计算

上一篇介绍的**通用计算**是关于多个`numpy`数组的计算, 本篇介绍的**聚合计算**一般是针对单个数据集的各种统计结果,同样,使用**聚合函数**,也可以避免繁琐的循环语句的编写。 # 元素的和 数组中的元素求和也就是合计值。 ## 调用方式 **聚合计算**有两种调用方式,一种是面向对象的

第一百一十六篇: JavaScript理解对象

好家伙,本篇为《JS高级程序设计》第八章“对象、类与面向对象编程”学习笔记 1.关于对象 ECMA-262将对象定义为一组属性的无序集合。严格来说,这意味着对象就是一组没有特定顺序的值。 对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值。正因为如此(以及其他还未讨论的原因),可以把 EC

开发者体验:现代企业架构的关键一环

在之前的文章中,我们详细介绍了平台工程的基本内容,文中指出平台团队应该采用产品的方法构建内部开发者平台,即 Platform as a Product。 内部平台面向的用户则是企业内其他部门的开发人员,因此如果要充分体现平台及平台团队的价值,那么打造优质的开发者体验(Developer Experi

第一百一十八篇: JavaScript 原型链式继承

好家伙,好家伙,本篇为《JS高级程序设计》第八章“对象、类与面向对象编程”学习笔记 1.原型链 原型链是JS实现"继承"的方案之一 ECMA-262把原型链定义为ECMAScript的主要继承方式。其基本思想就是通过原型继承多个引用类型的属性和方法。 重温一下构造函数、原型和实例的关系:每个构造函数

C++ 多级继承与多重继承:代码组织与灵活性的平衡

C++ 多级继承 多级继承是一种面向对象编程(OOP)特性,允许一个类从多个基类继承属性和方法。它使代码更易于组织和维护,并促进代码重用。 多级继承的语法 在 C++ 中,使用 : 符号来指定继承关系。多级继承的语法如下: class DerivedClass : public BaseClass1

MongoDB基础知识梳理

简介 MongoDB 是由 C++ 编写的开源 NoSQL 和基于文档的数据库。MongoDB 提供了面向文档的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常流行的文档类型数据库。 MongoDB 是非关系型数据库当中功能最丰富,最像关系型数据库的

[转帖]JVM——内存区域:运行时数据区域详解

https://www.jianshu.com/p/cded765cfd1b 关注:CodingTechWork,一起学习进步。 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象、一个是面向过程编程以外,我们还会从底层内存管理和垃圾收集方面作出比较。 对于C++

关于DDD和COLA的一些总结和思考

写在前面: 其实之前一直想汇总一篇关于自己对于面向对象的思考以及实践的文章,但是苦于自己的“墨迹”,一延再延,最近机缘巧合下仔细了解了一下COLA的内容,这个想法再次被勾起,所以这次一鼓作气,准备好好梳理一篇。至于标题,因为是被DDD和COLA唤起的,索性就叫这个吧。 思维:面向对象和面向过程 领域

[转帖]wiki Rust

Rust[编辑] 维基百科,自由的百科全书 跳到导航跳到搜索 此条目介绍的是由Mozilla主导开发的编程语言。关于“rust”在英文中的本意,请见“铁锈”。关于由Facepunch工作室所开发的一款游戏,请见“腐蚀 (游戏)”。 Rust 编程范型 编译语言、并发计算、函数式、指令式、面向对象、结