LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LvClass Concurrency

Solved!
Go to solution

Dear Community,

 

disclaimer:
i am not very expierienced in Labview so please forgive me if my code and concepts are not as ellegant as they should be.

 

i am expiereincing a problem with Labview Classes and Multithreading.
i try to describe the Problem, then i also have a example Project which hopefully makes it more clear to you

 

PROBLEM:
i have created a LvClass with some properties (dblValue, intValue etc...)
i create a simple GUI with a Queued State machine, where in the timeout of Consumer loop the Values are polled from a external device, and in the other cases values are written by FP-Objects-Value Changed events.
the polling creates a 50-70ms delay, due it is a external device this is not avoidable.
the GUI works fine on iths own, simply because the Class is written on one single point (the consumer loop of the queued state machine).
Now i whant to add a DIALOG to the GUI which sould also be able to write and read values.
The DIALOG is also a Queued State machine and a refernce of the LvClass is passed to the DIALOG from the GUI.
The DIALOG works the same way the GUI does except:
the reference must me derefernced and referenced in the consumer loop, and
the polling is done by the GUI so it is not necassary to do it in the dialog too.
Here is the Problem:
when i run the GUI everything works normal.
but when i then open the DIALOG the valaues in the GUI are still displayed normally, but in the DIALOG no Changes are recognized.

 

The CAUSE is also clear:
because in the Dialog the dereferenced Value is continously written back to the LvClass and in the GUI the polled values are diplayed directly after the polling.
So the State(values) of the Class does not change, because the DIALOG overrides it continously.

 

QUESTIONS:
Is it necessary to write the whole class to change only one Property?
Is is there a better way to write into LvClasses in more than one Loop/GUI/Thread/etc?
- The only solution i can think of now is using a queue or Semaphores, but i would like to use the class without any extras i have to think of when using it.
- i could put the Queue into the class but then i could not use the Property generation mechanims because i have t change every getter and setter.


here are some OFF-TOPIC questions:
Is there a build-in way to Create LvUserEvents(value Changes) for Properies, without doing it manually for every Property?
Is it Possible to create LvUserEvents directly on the LvClass wire to get a value Changed Event from seperate Properties?

 

Maybe another way to explain it:
when i have a class in C++ and this class has some properies (values accasable via getters/Setters), and i pass a pointer to that Class i can use the getter/setter methods to change one value.
i know that this value is not thread protected, and when i am not carefull i might get some troubles, but i do not have the write back the whole class to the pointer.

 

Thank you

gregor

0 Kudos
Message 1 of 3
(2,566 Views)
Solution
Accepted by topic author talorion

i am afraid i found no better solution than using queues and sort of pimpl:

example is here:

 

labview\examples\lvoop\ReferenceObject

 


Message 2 of 3
(2,541 Views)

Edit: Looks like you already found out about byref objects while I was writing this up. Smiley Happy


@talorion wrote:

Dear Community,

 


Is it necessary to write the whole class to change only one Property?

Is is there a better way to write into LvClasses in more than one Loop/GUI/Thread/etc?  

 

Sorry but I cannot address all of your questions right now. The first one it is easy if I understand the question - Yes. More correctly you have to write the whole object. The class is the definition and the object is the... object. When you instantiate an object from a class it is a value just like a boolean only it is obviously more complex. A better example is a cluster. If you have a cluster value in, and you update one element, then you have to write the whole resulting cluster to something. Just as you would put the cluster into a shift register you must do the same with an object.

 

If you have a cluster on a shift register in one loop then you cannot share that same object with another loop. You can send the value via queue but it is another copy or instance. Same thing with classes. What you can do if you want to access the same object in different loops is to use a by reference class. Do a search. I think there is an example in the example finder. There are a couple of ways to do this. One uses a single element queue which is just a regular queue with a max value of 1. The other way is to use a Data Value Reference. The DVR is the only data member in your class and it's type is a typedef which is a normal typedef that is private to the class. I imagine you could even use a global variable but have never heard of anyone doing that and in fact I only now just thought of it.

 

Which brings me to this. You really should avoid using global variables and local variables. It is possible to write extremely complex applications without ever touching them. Locals are fine in your GUI but still usually are not necessary. If you need to update a control then it is obviously OK. But looking at your dialog VI I see that you have several controls outside your loop with locals in the loop. Your DataClass in and StartedAsDialog locals may as well be removed and the controls wired instead.

 

Even if this is not a large application there is a lot of good information at the Large Apps page. Also check out the OOP page on Lava.

=====================
LabVIEW 2012


0 Kudos
Message 3 of 3
(2,539 Views)