Jump to content

I feel so dirty


Cat

Recommended Posts

You're right, I was a bit too explicit. I guess I was overcompensating. The basic point I wanted to make was that almost all the problems inherent to globals (memory allocations and mainly race conditions) are not solved if you use simple get/set FGVs and are sometimes made worse. Some people are probably not aware enough of this distinction because all they keep hearing is "globals are EVIL!!!! :!: " and "you need to use FGVs instead".

Link to comment

QUOTE (Neville D @ Mar 18 2009, 04:45 PM)

Aborting camera applications on RT causes the IMAQdx driver to be left hanging and the camera cannot be accessed until the system is rebooted, so I would say this is bad.
Ok, but those references could be open and closed by the still-running, not-aborted UI VIs. The state machine that's doing work that needs to be stopped doesn't have to do the cleanup. If you can't open all the needed references before the state machine starts running, you could have the state machine call back to the original VI hierarchy (though posting a message and waiting for response using two queues or user events) so that the orig hierarchy can open references on the state machine's behalf. That way those references survive the abort. Then when it does abort, the original VIs take care of closing any references that weren't closed explicitly by the state machine.

I'm still not saying this method is good or bad; I'm just walking through arguments to see if this path works. It seems like a more effective way to stop a process than having to code boolean checks all over your code, especially when LV has such nice hooks right in the assembly code at the end of each clump of nodes to detect abort.

Link to comment

QUOTE (Aristos Queue @ Mar 20 2009, 08:57 AM)

Ok, but those references could be open and closed by the still-running, not-aborted UI VIs. The state machine that's doing work that needs to be stopped doesn't have to do the cleanup. If you can't open all the needed references before the state machine starts running, you could have the state machine call back to the original VI hierarchy (though posting a message and waiting for response using two queues or user events) so that the orig hierarchy can open references on the state machine's behalf. That way those references survive the abort. Then when it does abort, the original VIs take care of closing any references that weren't closed explicitly by the state machine.

I'm still not saying this method is good or bad; I'm just walking through arguments to see if this path works. It seems like a more effective way to stop a process than having to code boolean checks all over your code, especially when LV has such nice hooks right in the assembly code at the end of each clump of nodes to detect abort.

But the state machine may do lots of other things that it needs to clean up besides just some open references. It may have files opens, data that should get logged, external equipment that it needs to stop or reconfigure. All of this functionality is unique to the the particular state machine and should not be exposed outside of it. This is basic encapsulation. The containing object (the state machine) should be the only thing that knows how to clean its self up. Even in the case of safety concerns and the need for immediate shutdown it is the state machine that should know what actions need to be taken to stop everything. Simply aborting the VI does not guarantee that all the stuff that needs to be stopped or turned off gets stopped off.

Abruptly aborting VIs should be used only in the most extreme conditions such as a non-responsive or run away VI as mentioned earlier. In all other cases it is best to handle the abort event in a graceful manner to ensure that the necessary cleanup gets run.

Link to comment

QUOTE (Aristos Queue @ Mar 20 2009, 08:57 AM)

.... It seems like a more effective way to stop a process than having to code boolean checks all over your code, especially when LV has such nice hooks right in the assembly code at the end of each clump of nodes to detect abort.

Reading that reminds me of Ed Dickens signature that reads;

"....using the Abort button to stop your VI is like using a tree to stop your car. It works, but there may be consequences.".

Ben

Link to comment

QUOTE (Aristos Queue @ Mar 20 2009, 06:57 AM)

I'm still not saying this method is good or bad; I'm just walking through arguments to see if this path works. It seems like a more effective way to stop a process than having to code boolean checks all over your code, especially when LV has such nice hooks right in the assembly code at the end of each clump of nodes to detect abort.

You might have some point here but understand that you are arguing against an ingrained and taught (even by NI) philosophy that says you should never abort a VI (or use ctrl+period). Using abort has very limited uses. I can see it used if you are absolutely sure that it won't cause problems or if you've designed it in to be aborted from the start.

Link to comment

QUOTE (Michael Aivaliotis @ Mar 20 2009, 10:56 AM)

You might have some point here but understand that you are arguing against an ingrained and taught (even by NI) philosophy that says you should never abort a VI (or use ctrl+period). Using abort has very limited uses. I can see it used if you are absolutely sure that it won't cause problems or if you've designed it in to be aborted from the start.
It's that last bit that I'm contemplating -- designing for abort. If you design the state machine to be aborted. Yedinak mentioned a bunch of stuff besides references that may need to be cleaned up. All of that could be back in the main VI, sitting right after the call to the Run VI method.

Your biggest danger is still with the hardware interactions -- don't let anything I post here dissuade you from that. But I am suggesting that "Never use the abort button" is very different from "never use the Abort method", maybe. The Abort button you might use on just any VI, with no clue as to what you're aborting or how safe it is. The Abort method you'd be laying in as a deliberate stop mechanism.

Anyway... idle musings from a C++ programmer. One of you G programmers should explore this idea and let me know how it turns out.

Link to comment

QUOTE (Jeffrey Habets @ Mar 21 2009, 06:28 AM)

This is actually what I do in most all of my code.. All my parallel processes are implemented as active objects. The object takes care of allocating all necessary stuff before spawning the process and cleans up afterwards. Depending on the nature of the task of the process, I'll simply use an "Abort VI" to stop the process or a message with response notifier. For me, the usage for one over the other is about 50/50 I guess.

For whatever it's worth, NI provided a framework that uses the Abort approach for the FIRST Robotics projects. The "autonomous mode" VI (the part that runs the robot without any user interaction) is run by reference and aborted when the autonomous period of the competition (usually the first 15 seconds) ends. All references are opened in the main VI and stored in global variables; it looks a little weird to me as a LabVIEW programmer but allows the students to get their code working without getting into queues or notifiers and makes it easy to stop the autonomous mode when necessary.

Link to comment

QUOTE (Jeffrey Habets @ Mar 21 2009, 06:28 AM)

Jeffrey,

Let me stop and thank you for that image of your active objects! That diagram reflects very well the scheme I used in when I guessed at how to implement active objects. I feel like I took a wild guess at bonus Q on a test and ended up with full credit! Whooo hooo!

Re: Aborting and keeping refs in the top level VI...

Seems like we are breaking some LVOOP rule by making the top level responsible for low level refs etc.

Ben

Link to comment

QUOTE (neBulus @ Mar 21 2009, 07:37 AM)

Seems like we are breaking some LVOOP rule by making the top level responsible for low level refs etc.

I'd counter with the question: who is really the owner of those refs if they have to outlive the state machine? And, actually, it doesn't need to be the top-level that is responsible for those refs. We could have a wrapper around the state machine that is responsible for the refs used by the state machine, and the top-level calls to the wrapper. The encapsulation would then hold.

Link to comment

QUOTE (Jeffrey Habets @ Mar 21 2009, 03:28 AM)

This is actually what I do in most all of my code.. All my parallel processes are implemented as active objects. The object takes care of allocating all necessary stuff before spawning the process and cleans up afterwards. Depending on the nature of the task of the process, I'll simply use an "Abort VI" to stop the process or a message with response notifier. For me, the usage for one over the other is about 50/50 I guess.

Jeffrey, I also do this however I use dynamic events or queues to stop the process. Never abort.

I don't like imposing rules on things like this because even though you can have general guidelines and best practices, it really depends on the specific application at hand, the corporate style guidelines and (at the end of the day), the comfort level of the programmer.

So I'm not saying you should never use abort, but it needs to be designed-in and all editors of the code must understand the caveats of this method.

Link to comment

QUOTE (neBulus @ Mar 21 2009, 02:37 PM)

Your welcome. :) I actually just finished it for a presentation I have coming up and thought it would well fit in. Pictures say so much more that words imho.

QUOTE (Michael Aivaliotis @ Mar 22 2009, 05:15 PM)

Jeffrey, I also do this however I use dynamic events or queues to stop the process. Never abort.

Where I talked about message and response notifiers, I of couse meant the dynamic events or queues. (Although it could be done using object attributes..)

And if you really want to make sure that the thread is finished before you take other actions in your destroy method, let the thread send you some kind of notifier when it's finished.

QUOTE (Michael Aivaliotis @ Mar 22 2009, 05:15 PM)

I don't like imposing rules on things like this because even though you can have general guidelines and best practices, it really depends on the specific application at hand, the corporate style guidelines and (at the end of the day), the comfort level of the programmer.

So I'm not saying you should never use abort, but it needs to be designed-in and all editors of the code must understand the caveats of this method.

I coudn't agree with you more.. In the case of active objects the handling of the active process is fully encapsulated, so the users of the objects don't have to bother knowing what's going on inside. However, for developers that work on the object's internals it's important to know what's going on, so good documenting of the destroy method is a must here.

When I use the abort method, it's mostly on AO's with a thread that does nothing more than just one thing (e.g. continuously gathering data and pushing it on to a queue or listening on a communication channel and passing the events on to a higher level). If I have no need to send commands to the thread and it's a safe loop to just abort it, I will.. By design.. :)

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.