LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Communication Between Parallel Actors

Solved!
Go to solution

Hi,

I did exactly that. I created two actors and stored the enqueuer of each actor in other Actors private data and launched the actors and send the message with the enqueuers. 

govindsankar_0-1710368872481.png

govindsankar_1-1710369750009.png

 

This is the launcher which launches two actors A and B. Then Send Write A Enqueuer sends Actor A's Enqueuer to B and vice verse. 

 

Then inside actor core of Actor A i have created a numeric control and in actor B I have created a numeric indicator. Then I created a reference to the numeric indicator in B and then created a control of the reference and then stored that control in the private data of actor B and then created a function to update the numeric control using property node. 

govindsankar_2-1710369831589.png

 

Then I created a message for this function and used this message in Actor Core of A to update the value. B's enqueuer is obtained by unbundling the private data of A and there is a numeric control in A and its value is given to the message along with B's enqueuer. 

govindsankar_3-1710370042903.png

This is actor core of A.

 

govindsankar_4-1710370138105.png

This is actor core of B.

 

And what I expect is when i change the numeric control in Actor core of A, it automatically changes the numeric indicator in actor core of B. But it is not happening.

 

So I did this same question as nested actors, where launcher launches A and A launches B, so there was no need to send enqueuer, B's enqueuer was already available in A and I ran the program there and it worked. So with nested actors it worked, but with parallel actors it is not working. Why is this? What am i doing wrong. If the pictures are not good please be free to check the zip file that contains the entire program. Thank you.

0 Kudos
Message 11 of 21
(588 Views)

The issue is that you have blocking code in your actor cores, the user event loops ( and any other blocking code ) will prevent the actor core ( for the actor base class ) from running which prevents any messages from being processed. Typically your actor cores should do very little. Remove all the code from the actor core and instead make an actor method that pops up a window to indicate the state of the actor. A down side of actors is that you have to do extra work to use them with user event loop VIs like in standard labview code. 

______________________________________________________________
Have a pleasant day and be sure to learn Python for success and prosperity.
0 Kudos
Message 12 of 21
(579 Views)
Solution
Accepted by govindsankar

Blocking code is not the problem here. The parent Actor Core will execute in parallel to the UI.

 

Check the error output of Send Update Numeric Indicator. The enqueuer is invalid.

 

When you read the enqueuer of Actor B in Actor A's Actor Core, you are reading from the state before it received Actor B's Enqueuer.

 

Create another message that you can send from AC-A to itself that uses the enqueuer from the current class data for Send Update Numeric Indicator.

 

 

 

Message 13 of 21
(555 Views)

I did not try to debug your code but here is a simple example I made where a regular VI launches two instances of the same actor that can send messages to each other:

LucianM_0-1710407163323.pngLucianM_1-1710407182039.png

 

Lucian
CLA
Message 14 of 21
(540 Views)

Hello @LucianM,

 

thank you very much but could you release that in LabVIEW 2016. Is it possible? Thank you. 

Message 15 of 21
(531 Views)

Here is the project saved for LV16.

Lucian
CLA
Message 16 of 21
(525 Views)

@cordm wrote:

Blocking code is not the problem here. The parent Actor Core will execute in parallel to the UI.

 

Check the error output of Send Update Numeric Indicator. The enqueuer is invalid.

 

When you read the enqueuer of Actor B in Actor A's Actor Core, you are reading from the state before it received Actor B's Enqueuer.

 

Create another message that you can send from AC-A to itself that uses the enqueuer from the current class data for Send Update Numeric Indicator.

 

 

 


I was totally wrong, sorry for the bad advice. 

______________________________________________________________
Have a pleasant day and be sure to learn Python for success and prosperity.
Message 17 of 21
(508 Views)

Thank you. I did exactly what cordm told me to do to and I was able to solve it. Now I have two actors, and I am able use numeric, string and boolean controls in actor a to control numeric, string and boolean indicators in actor b and also vice versa. Thank you very much for helping. But now comes the final part of the program. Earlier I had a stop button in both actors and I stop them individually. Now I need to update the program to stop both actors with either of the stop buttons. That is if I press stop button of Actor A, then both A and B should stop and vice versa. How i tried to do is the same as sending the numeric value. But instead of sending a numeric value, I am trying to send a user event. Pressing stop creates a user event called stop and I send it exactly the same way as I send the numeric value. That is I created a user event control in the private cluster data of both actors and I use that to send the user event. So i press stop in A, the user event is generated and this is then send as a message to actor b and in the user event is executed in the event structure to stop and close the actor. But this is not working. I believe this is due to me not understanding of user events properly. Please check the code and let me know where have I made the mistake. Also for now only stopping from A to B is done. I havent implented B to A, since A to B stopping is not working. Thank you. 

0 Kudos
Message 18 of 21
(495 Views)
Solution
Accepted by govindsankar

Yes, you should learn a bit more about user events.

The user event refnum is never created, it is just a constant that cannot be used for anything.

That invalid refnum is sent to one actor that just stores it. The actor that receives the user event refnum could generate an event in the sending actor using that refnum. Don't do that. Do not use user events to communicate between actors, use messages.

 

All you need to do is to send a stop message to the other actor when one actor terminates.

 

You also need to make sure your helper loop stops.

 

Look again at what LucianM posted:

- create user event

- register for that event

- call actor core

- generate event after actor core returns (ignoring errors!)

- destroy user event

 

You can also do that in other VIs:

  • override Pre-Launch Init
    • create and store the stop event refnum
  • override Stop Core
    • generate the stop event, then destroy the refnum
    • send stop message to other actor
Message 19 of 21
(480 Views)

govindsankar_0-1710439209962.png

So this is the stop core of A. I tried what you told me, overriding prelaunch init and stop core. And it worked. Stopping one, stopped both. Thank you very much

 

0 Kudos
Message 20 of 21
(470 Views)