05-11-2021 02:40 AM
Hi!
In an attempt to run asynchronously multiple sub-vis that are controlling a testbed, I thought that it could be a good idea to have the same "Stop" event (and especially the same Reg Events refnum) to make them all exit nicely (they are all base on the Prod/Cons event template).
But it looks like it is not working.
My guess right now is that there is some competition between the different event loops running asynchronously, the first one to read the event would delete it and the other wouldn't be able to see it? Is that possible? It seems that according to this thread from 2007 this is the case, but I would have thought that 14years later that might have changed.
A quick test showed me that running multiple Reg events and sending one per loop works fine, is that how you would deal with it?
Or maybe also having multiple Prod/Cons running asynchronously and sending messages and events to each others is not a good idea?
Thanks for your advice.
Best,
VInny.
Solved! Go to Solution.
05-11-2021 05:40 AM - edited 05-11-2021 05:41 AM
05-11-2021 06:02 AM - edited 05-11-2021 06:13 AM
Woopsie
Yes, I understand that, a mistake while trying to draw a quick example 😬 thank you for noticing. The other event case in Loop 3 is checking on the Quit button (like the other loops btw)
Do you have any advice concerning my first problem?
As I see it, my current options would be:
Does it make sense?
05-11-2021 06:44 AM
Wait is your updated diagram not working? it looks fine to me...
If I understand your second question, I do this sometimes- I employ one stop message via user events for messaging other sub-processes that do not have complicated shutdown procedures, and it typically works fine, but I also imagine the level 99 devs on here might shun me for it.
If I have sub-processes that are complicated enough to have to do-some-stuff to close, then I actually put some more complicated messaging in place that allows for confirmation of the sub-processes closing, with a timeout and error handling in place... There have been many instances where I didnt do this, then had to debug and figure out why my top level app wasn't exiting or closing when asked...
If you're not familiar with using user events in a self-addresses-messaging kind of way, it's become something I use often and has been working well for a long time, something like this:
where "QSM1" and "QSM2" are different vi's - and QSM1 asynchronously launches QSM2 after registering for the event that QSM2 is passed. When QSM2 generates the event, it includes an event that it is listening/registered for, and when QSM1 handles the event generated by QSM2, it can respond on the event that came with it. I wonder if I worded this well enough for it to make sense, or if it's just some user-event soup 🤣 you can also do this with queues too but the handoff is a bit more complicated...
I've also become aware of some caveats to using user events for messaging that we should all be aware of, particularly the relationship between user events and labview root loop, which you could get into trouble with if you're using modal windows and whatnot...
05-11-2021 08:40 AM
@p27 a écrit :
Wait is your updated diagram not working? it looks fine to me...
It does work! I'm just wondering if this is a correct way of doing it ! I'm still not really used to create application from nothing (by nothing I mean people coming to me and I have to figure out what they want) to the end-user working program.
And I'm just trying to not catch bad habits 🙂
@p27 a écrit :
If you're not familiar with using user events in a self-addresses-messaging kind of way, it's become something I use often and has been working well for a long time, something like this:
where "QSM1" and "QSM2" are different vi's - and QSM1 asynchronously launches QSM2 after registering for the event that QSM2 is passed. When QSM2 generates the event, it includes an event that it is listening/registered for, and when QSM1 handles the event generated by QSM2, it can respond on the event that came with it. I wonder if I worded this well enough for it to make sense, or if it's just some user-event soup 🤣 you can also do this with queues too but the handoff is a bit more complicated...
Huuuum, ok? 😂
If I understood well:
You create an Inception event where the data type is a cluster of <1 string + 1 "user event - String data typed"> that way your sub-vi can confrim reception of the event by sending a response to the "User event - Str data typed" - Correct?
Tbh I don't really see the point of it 🤔. Notifiers do this very well, no?
05-11-2021 09:35 AM
You create an Inception event where the data type is a cluster of <1 string + 1 "user event - String data typed"> that way your sub-vi can confrim reception of the event by sending a response to the "User event - Str data typed" - Correct?
yep, you got it.
And regarding your first question, I use user events for this kind of stuff all the time so I'm inclined to say it's just fine.
And for the example/idea i mentioned, yes you could certainly use notifiers if you wanted to, but the self addressed messaging structure allows you to support data in the messages if desired for more than just stop messages...
I tend to just use one string based event since most things can be interpretted in the receiving vi, and unflattened/flattened to string if need be... it's also common for people to use string+variant data clusters... that user event is how i tell the other process what to do, including when to stop running.
I'm not suggesting it's necessary for simple stop messages, but when it comes to multiprocess communication some form of async messaging is a must in my opinion.
05-11-2021 10:55 AM
You should use one Register For Events function per loop. Do not split the Register For Events wire to connect multiple Event structures.
Your code will work fine as you've written it, but I'd make one minor change- wire the Unregister For Events to the output Dynamic Event Registration terminal. It should work the same (assuming you're not switching events inside the case structure) but it'll be a little more clear what's going on, and will be tolerant to switching around registrations internally.
You can also split the User Event refnum into multiple Register For Events nodes if you want to send one event to multiple Event structures. The User Event itself can be split as much as you'd like; the Event Registration Refnum should *not* be split (for purposes of multiple registrations... the way you have it in your first post is fine since you're using the split version to unregister).
I have found that the documentation is sometimes correct and sometimes wrong on this one, and it's been fiddly in the past. Using multiple RFE's means you know for sure you won't have race conditions. I can theoretically come up with reasons to just use one, but be warned: this kind of code WILL break at some point in the future. See the discussion and my example code in this thread:
This is specifically discussing the Actor Framework, but the points about event registrations still apply. Note that the "helper loops" discussed in that thread are basically just "second loops" that often have Event Structures in them.
05-11-2021 11:22 AM - edited 05-11-2021 11:26 AM
[Reply below obsoleted by the time I got around to replying without remembering to refresh first. Bert McMahan's reply already covers things more thoroughly.]
Getting back to the initial question:
Create 1 "Stop" event and pass that 1 event ref to multiple "Register for Events" functions. Each Event Structure that will react to your "Stop" event needs to have its own call to "Register" to get its own unique Registration Refnum.
It's also advisable to make sure at exit time that you get through all your "Unregister" calls before you Destroy your "Stop" event.
-Kevin P
05-11-2021 11:43 AM
Cool thanks a lot!
I will apply the necessary changes in my application then 🙂
@Kevin_Price a écrit :
It's also advisable to make sure at exit time that you get through all your "Unregister" calls before you Destroy your "Stop" event.
-Kevin P
So I never knew exactly whcih one to call first, I guess that answer my question. But in my case, I anyway close everyting at the very end, when all loops are closed anyway, so the order wouldn't be an issue, would it?
05-11-2021 12:09 PM
I adopted the "rule" to unregister all the Registration refs prior to destroying the Event ref based on one or more discussions here (or maybe over on LAVA) many years ago. I don't remember details of the discussion any more, just the take-away lesson.
My very vague recollection leads me to say this, but not with any substantiation: I *think* that you can often "get away with" either order if you're halfway into your exit process anyway.
-Kevin P