LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

It's impossible, but it happens.

Solved!
Go to solution

particularly the event structure inside a case structure (this is often a bad idea since the event structure will still queue events even when that case isn't active)

 

But that's exactly the purpose - it's an action engine.  If the action queue is empty, it provides a "Nothing" action, which means we wait on an event.  An event might put one or more action codes into the queue, and they will be handled.  I DO want to pile up events.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 11 of 26
(1,842 Views)

You open a reference to the VI and run it nearly 1,000,000 times with lots of VI Server references? While I've never tried to do anything on that sort of scale before I really wouldn't be surprised if you were having some serious performance issues. I would perhaps look at using the Asynchronous Call by Reference node as it might give you some performance improvements?

 

Have you looked at your memory usage and/or tried to use the Desktop Execution Trace Toolkit to see if you have any unclosed references when your application stops (look for yellow lines when the app closes)?

 

Also - you should change from using VI Path to VI Name in your launcher code so that it uses the copy in memory (from the static VI reference) rather than trying to load it from disk.


LabVIEW Champion, CLA, CLED, CTD
(blog)
0 Kudos
Message 12 of 26
(1,842 Views)

You open a reference to the VI and run it nearly 1,000,000 times with lots of VI Server references?

 

Not sure where you get the 1,000,000 number.  The numbers in the log file are mSec times.

 

 

 

 While I've never tried to do anything on that sort of scale before I really wouldn't be surprised if you were having some serious performance issues.

 

I have a previous edition of this same scheme, which works fine.  72 simultaneous copies of the same VI.  I can't figure out the difference between that edition and this.

I do need to be sure of complete shutdown now, whereas the previous edition, I didn't care.

 

 

 

I would perhaps look at using the Asynchronous Call by Reference node as it might give you some performance improvements?

I tried the CALL and FORGET and CALL and COLLECT methods.  Same basic problem.

 

 

 

Have you looked at your memory usage

 

--- Memory usage goes up and down when the window opens and closes, as I would expect.  It returns to the same point.

 

 

and/or tried to use the Desktop Execution Trace Toolkit to see if you have any unclosed references when your application stops (look for yellow lines when the app closes)?

 

I've never used the DETT.  I do know that, even though the program has quit, if I open the block VI (the one with the 72 copies of), it shows up as "reserved", for a while.   I believe that's a symptom, not a cause.  The queue problem lets me quit before it's really done.

 

 

Also - you should change from using VI Path to VI Name in your launcher code so that it uses the copy in memory (from the static VI reference) rather than trying to load it from disk.

 

THAT is useful info.  It asks for a path, so I give it a path, but I've seen examples that use the name.

 

Thanks.

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 13 of 26
(1,828 Views)
Solution
Accepted by CoastalMaineBird

@CoastalMaineBird wrote:

 

But I never touch that queue, not even to destroy it, except in two places:

1...  When the block starts, I put an element in, when it stops, I take an element out.


A reference is owned by the the hierarchy it was created in. The hierarchy is defined by the top level VI, which each dynamic VI is. That means that the first VI that calls the global VI owns the reference. Presumably that's one of the dynamic VIs, because you say the main one only calls it after launching to monitor the queue.

 

When the hierarchy goes idle, all the references it owns are destoryed, explaining how you could get an error 1 and a 0 and why the loop would stop. This is why you should handle errors and if you don't, have automatic error handling on.

 

The solution for this is simple - call the global VI in the main VI before launching any of the blocks.

 

As a side point, you don't actually need the 999s to index the for loop when launching. The N terminal doesn't need to be wired and I hardly ever wire it. Edit - presumably, that's where the 1,000,000 comes from. When I saw those I also thought "that's a lot of VIs".

 

As another side point, the desktop exec trace toolkit is good for finding out what happens with resources like queues.


___________________
Try to take over the world!
Message 14 of 26
(1,827 Views)

I replaced the queue generation mechanism with the conventional WHILE loop plus Uninitialized ShiftReg pattern, rather than the feedback node which I just recently tried.

 

The first time after that, I got no QUEUE error.  But the second and subsequent times, I did.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 15 of 26
(1,819 Views)

As a side point, you don't actually need the 999s to index the for loop when launching. The N terminal doesn't need to be wired and I hardly ever wire it. Edit - presumably, that's where the 1,000,000 comes from. When I saw those I also thought "that's a lot of VIs".

 

Oh, I see.  Those are simply a place for me to put in a "1" or "2" to limit how many copies I run, for debugging purposes.

 

The real case is limited by the number of tabs (12) and the number of subpanels per tab (6).

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 16 of 26
(1,812 Views)

Sam_Sharp wrote:

Also - you should change from using VI Path to VI Name in your launcher code so that it uses the copy in memory (from the static VI reference) rather than trying to load it from disk.


I think this won't make any difference. From an old set of LabVIEW upgrade notes that I happened to be reading the other day looking for details on a different change, "In LabVIEW 8.0.x and 8.2.x, if the name of the VI from the vi path input matches the name of a VI in memory on that target, LabVIEW returns a reference to the VI in memory and LabVIEW does not load the VI specified in the vi path input. In LabVIEW 8.5, if the name of the VI from the vi path input matches the name of a VI in memory on that target but the paths differ, the Open VI Reference function returns an error."

Unless this has changed again (and I don't think it has), in this case the VI will load from memory because the VI name and path are identical.

0 Kudos
Message 17 of 26
(1,810 Views)

@CoastalMaineBird wrote:

I replaced the queue generation mechanism with the conventional WHILE loop plus Uninitialized ShiftReg pattern, rather than the feedback node which I just recently tried.

 

The first time after that, I got no QUEUE error.  But the second and subsequent times, I did.


Whether you store it in a feedback node or shift register makes no difference. As tst pointed out, the issue is which top-level VI causes the queue to be created. You need to make sure that it's the main VI, and not one of your dynamically-launched subpanels.

0 Kudos
Message 18 of 26
(1,803 Views)

A reference is owned by the the hierarchy it was created in. The hierarchy is defined by the top level VI, which each dynamic VI is. That means that the first VI that calls the global VI owns the reference. Presumably that's one of the dynamic VIs, because you say the main one only calls it after launching to monitor the queue.

 

 

Oh, THAT is new info for me.  Regardless of whether anybody killed it, it's destroyed whenever it's "parent" dies.  The parent is probably block #0, the first one to start running.

But block #0 dies at some random time after the STOP event - they don't die in order.

 

When the hierarchy goes idle, all the references it owns are destoryed, explaining how you could get an error 1 and a 0 and why the loop would stop.

--- Yes, I can see that now.

 

This is why you should handle errors and if you don't, have automatic error handling on.

 

But, but, but, it can't possibly have an error there ! (How many times have you heard that?)

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 19 of 26
(1,797 Views)

A reference is owned by the the hierarchy it was created in. 

 

It makes no sense to me WHY that would be the case, but it certainly seems to be true, and THAT is the root of my whole problem.

 

 If I simply place a call to that GET THE QUEUE vi, in my main app code (before any of this can happen), then the queue error goes away.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 20 of 26
(1,779 Views)