LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

OOP - how to pass variables between object branches, but not VI instances

Solved!
Go to solution

I have a main VI where an object wire passes through some initialization subVIs and then branches to multiple parallel loops. My understanding is that each branch becomes a separate instance of the object. Data is passed between the loops using global variables wrapped into accessors (I can change this if someone has a better approach - minimizing memory and CPU usage is very important).

 

I need to have a large number of instances of the main VI running at the same time. What would be the best way to make sure that the data passed between the loops of one VI instance do not interfere with the data passed between the loops of another VI instance?

 

Thank you for your insight.

 

0 Kudos
Message 1 of 10
(5,116 Views)

This is somewhat difficult to answer without seeing your code but I'll take a stab.

  1. Global variables are evil. Stop using them. (Ok they really aren't evil, but they are rarely needed)
  2. Seeing your code would really help for suggesting a replacement
  3. Try using a SEQ (Single-Element-Queue) instead of the global variable. This assumes that the SEQ is generated in Main. Leave the Queue unnamed and pass the reference obtain through "Obtain Queue" to the classes. Set Main to not share memory between clones. Now every place that you drop down the Main vi, it will generate it's own SEQ that cannot be accessed outside of Main.
Charles Chickering
Architecture is art with rules.

...and the rules are more like guidelines
0 Kudos
Message 2 of 10
(5,110 Views)

As Charles_CLA said: avoid global variables, and upload your code.

 

As an alternative to single-element queues, you could wrap the shared data in a Data Value Reference (DVR) inside the class. This would let you share data between branches of the same wire, while keeping data separate between different branches. It is also memory-efficient when used properly.

0 Kudos
Message 3 of 10
(5,097 Views)

I originally had queue references in the .ctl for the .lvclass of my Object. During initialization of the Main VI, I used the Obtain Queue and set it with a write accessor; after the Object wire split into the multiple parallel loops, I would use accessors to attempt to write to the queue in one loop and read from it in another. Data wasn’t being passed between the loops, so I figured that branching the Object made separate instances of the Object with their own individual queues. Hence I held my nose and used Global Variables. Does it sound like I was doing something incorrectly?

 

I did name the queues. Why is it important to not name the queues?

 

I do need to pass information from the set of Main VIs to yet another VI, so I am concerned that setting the Main VIs to not share memory may not allow that.

 

I can’t post the actual code, but I can see about posting a non-proprietary version.

0 Kudos
Message 4 of 10
(5,080 Views)

If you do not name the queues, then they cannot be referenced without the wire, hence allowing you to duplicate Main and have two separate queues. If the queues are named, then the first time you call main, the queue is created, the second time you simply return a reference to the original queue. It does indeed sound like there was something wrong if you were not able to pass data between the loops using the queue, this is one of the primary reasons we have the queue. The non-proprietary code would be very helpful. The code doesn't have to be functional, just draw out the loops and give us an idea of what you are trying to accomplish, code comments are your friend 🙂

Charles Chickering
Architecture is art with rules.

...and the rules are more like guidelines
0 Kudos
Message 5 of 10
(5,075 Views)

I agree, there are too many degrees of freedom here to give a definitive answer without having some idea architecturally what you're trying to achieve.

 

Post some code or at least pseudo-code.

 

Shane.

0 Kudos
Message 6 of 10
(5,069 Views)

Global wrapped in accessor? Is that the same as a FGV/AE with globals? AE, Action Engine is a decent way to share information between loops and memory efficient. Be careful to not abuse it though, the same warnings as with Globals and Locals apply, to a lesser degree. 🙂

 

G# uses DVR'ed objects to get referenced objects so you can split the wire and use the SAME object. 😄 Only a new Create actually creates a new object.

 

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 7 of 10
(5,063 Views)

Thank you everyone for your help so far, I really appreciate it. I've put together a very simple example of what I am trying to do. See attached. The queues work now in this example, so I must have made a mistake in my full set of code.

 

Not naming the queues works great! That solves part of the problem. However, it is not clear to me how to pass the string data of Queue A out to another VI. Any suggestions?

0 Kudos
Message 8 of 10
(5,046 Views)

Chris_12345 wrote:

Not naming the queues works great! That solves part of the problem. However, it is not clear to me how to pass the string data of Queue A out to another VI. Any suggestions?


In your example, if you want all instances of the class to share Queue A for passing messages to Viewer, then you should create Queue A at the top level and pass that queue reference into each separate instance of Class, as well as to Viewer, so that they all share the same queue reference. In addition, Viewer probably should not be a member of Class, since it doesn't do anything with the class data.

0 Kudos
Message 9 of 10
(5,035 Views)
Solution
Accepted by Chris_12345

Ah, you are right. Dumb mistake on my part. It is all working now. Attached is the corrected code.

0 Kudos
Message 10 of 10
(5,032 Views)