LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how to code a parallel 'for loop' and 'while loop' where the while loop cannot terminate until the for loop has finished?? (queues also present)

I've attached a sample VI that I just cannot figure out how to get working the way that I want.  I've labeled the some sections with black-on-yellow text boxes for clarity during the description that follows in the next few sentences.  Here's what I want:
1) overall -- i'm intend for this to be a subVI that will do data acquisition and write the data to a file.  I want it to use a producer/consumer approach.  The producer construct is the 'parallel for loop' that runs an exact number of times depending on user input (which will come from the mainVI that is not included).  For now I've wired a 1-D array w/ 2 elements as a test case.  During the producer loop, the data is acquired and put into a queue to be delt with in the consumer loop (for now, i just add a random number to the queue).
2) the consumer construct is the 'parallel while loop'.  It will dequeue elements and write them to a file.  I want this to keep running continuously and parallel until two conditions are met.
      i. the for loop has finished execution
      ii. the queue is empty.
   when the conditions are met, the while loop will exit, close the queue, and the subVI will finish. (and return stuff to mainVI that i can deal with on my own)

Here's the problems.
1)  in the "parallel for loop" I have a flat sequence structure.. I haven't had time to incorporate some data dependency into these two sequential sections, but basically, I just care that the "inner while loop" condition is met before the data is collected and queued.  I think I can do this on my own, but if you have suggestions, I'm interested.
2)  I can easily get the outer for and while loops to run sequentially, but I want them to run in parallel.  My reasoning for this is that that I anticipate the two tasks taking very different amounts of time. .. basically, I want the while loop to just keep polling the queue to get everything out of it (or I suppose I could somehow use notifiers - suggestions welcome)...  the thing is, this loop will probably run faster than the for loop, so just checking to see that the queue is empty will not work... I need to meet the additional condition that nothing else will be placed in the queue - and this condition is met when the for loop is complete. basically, I just can't figure out how to do this.
3) for now, I've placed a simple stop button in the 'parallel while loop', but I must be missing something fundamental here, because the stop button is totally unresponsive.  i.e. - when I press it, it stays depressed, and nothing happens.

suggestions are totally welcome!
thanks,
-Z

 
0 Kudos
Message 1 of 14
(3,822 Views)
and I can't figure out how to edit my messages (where is the damn button!?!?!)

but i wanted to add, that in order to simplify the code,  I took some instrument dependent code out of the 'inner while loop' which is why that condition looks sort of weird.
-Z
0 Kudos
Message 2 of 14
(3,803 Views)
There are many ways to do this. I would add a small loop after the FOR loop where you wait until the queue is empty, then release it right there.
 
In the while loop, just stop when the dequeue creates an error. This means the queue is empty and has been released. 🙂
 
Modify as needed.
0 Kudos
Message 3 of 14
(3,792 Views)
First off, thank you.  I think the simple while loop after the FOR loop is a nifty way to do this because it will always run until the the queue is empty since the dequeueing is done in a separate loop!  thanks for that idea.

now let me ask some questions!

altenbach wrote:
In the while loop, just stop when the dequeue creates an error. This means the queue is empty and has been released. 🙂

the problem i'm having with this part is that I can forsee this situation --- if the 'dequeue while loop' is running at a much faster rate than the FOR loop, it should generate an error if it tries to dequeue an element that isn't there yet.  If that happens, that loop will stop.  if the FOR loop then dumps something into the queue, the program will hang because the queue will never be empty.

perhaps I'm missing something, but it seems like this is a possibility.

.... i decided to test this by adding a delay to the for loops before I actually posted the message and now I'm a bit more confused...

I was under the impression that the 'dequeue while loop' would just keep cycling at a very rapid pace (since I'll i'm doing is checking the queue).  I figured that this would mean that a large percentage of the time, it would try and dequeue an empty queue and once in a while (when the FOR loop finished) the while loop would actually have something to dequeue.  however this doesn't seem to be the case.  The only understanding I can come to is that the 'dequeue while loop'  only runs when the queue has been populated.  almost as if it is receiving a notifier telling it to run b/c the queue is populated.

can you make any sense of this to me?

-----begin edited text-----
So i read a bit more about the 'dequeue element' function, and as I understand it, since there is no timeout wired to the dequeue element function, it will wait forever, thus the race condition I suggested above can never happen!

As a side note -- I'm leaving all this internal dialog in here so that future readers will see why your solution works so well!
-----end edited text-----

thanks again! -- and please correct me if I'm still seeing this wrong!
-z

Message Edited by zskillz on 10-19-2006 11:54 PM

0 Kudos
Message 4 of 14
(3,781 Views)


@zskillz wrote:
So i read a bit more about the 'dequeue element' function, and as I understand it, since there is no timeout wired to the dequeue element function, it will wait forever, thus the race condition I suggested above can never happen!

Yes, you got it! 😄

0 Kudos
Message 5 of 14
(3,768 Views)
I tried to open your VIs but it doesn't work. LV is launched, the dialog box (new, open, configure...) opens and then... nothing. Not even an error message. I guess it isn't a problem of LV version or a dialog box would appear saying this. Could you, please, send a image of the code?
Thanks,
Rasputin
LV7.1 <> W2K
0 Kudos
Message 6 of 14
(3,761 Views)
I'd actually like to add a little more, since I thought about it a bit and I'm still not quite certain I understand the sequence of events...

@altenbach wrote:

@zskillz wrote:
So i read a bit more about the 'dequeue element' function, and as I understand it, since there is no timeout wired to the dequeue element function, it will wait forever, thus the race condition I suggested above can never happen!

Yes, you got it! 😄


As I've thought about it a bit more, there's a few things that surprise me... first, the reason the 'dequeue element while loop' errors is not because there's nothing in the queue, it's becaues the queue has been released and it's trying to access that released queue...   However the problem I have is this --- Even though there's no timeout wired to the dequeue element, I still would think that the while loop that contains it would continue to run at whatever pace it wanted -- and as i said before.. most of the time, it would find that there is nothing to dequeue, but once in a while, something is there.  however, it seems that this loop only runs when something has been enqueued.  the reason I say this is illustrated in the next code sample MODv2 that's attached below.  I've added a stop button to the "queue size while loop" so the program runs until that is pressed.  I've also added a simple conditional in the "dequeue while loop"  that generates a random number if it a button is pressed... but this button is totally non-responsive... which means to me that the "dequeue while loop" isn't actually continuously running, but only when an element is added to the queue.  this still seems almost like the 'dequeue while loop" waits for a notifier from the queue telling it to run.  can you explain this to me? because it is different from what I expect to be happening.



@Rasputin wrote:

I tried to open your VIs but it doesn't work. LV is launched, the dialog box (new, open, configure...) opens and then... nothing. Not even an error message. I guess it isn't a problem of LV version or a dialog box would appear saying this. Could you, please, send a image of the code?
Thanks,

Hi Rasputin, I'm using LV8.  I assume that was your problem, but who knows.  I've attached a pic of of altenbach's solution since it's what I needed.


thanks
-Z

Message Edited by zskillz on 10-20-2006 11:49 AM

Download All
0 Kudos
Message 8 of 14
(3,737 Views)

Labview function define the default behavior for each input if it is not wired. If you create a subVI, you can set reasonable default values for each control, which then would be used in case it is not wired.

The default value for the timeout in the dequeue function is intentionally defined as "-1" (not as zero!), meaning that it will wait forever until an element is available (as described in the help) if it is not wired. You can overwrite that with any timeout value you want by connecting a diagram constant or control.

The more you learn about LabVIEW, the more you appreciate the amount of thought that went into the design. Things are really optimized for the most typical use and greatest functionality. If there is no new element to process, why spin the loop? 😄

0 Kudos
Message 9 of 14
(3,726 Views)


@altenbach wrote:
    The more you learn about LabVIEW, the more you appreciate the amount of thought that went into the design. Things are really optimized for the most typical use and greatest functionality. If there is no new element to process, why spin the loop? 😄

but that's exactly my question/problem..  If other controls are placed in that loop, then it would need to spin.  -- and I'm surprised that it doesn't if that's the case....  I assume that this is LV's way of telling me that I should  not put other controls in that loop, but instead somewhere else?

-Z

btw - you've been quite helpful, so thanks again.
0 Kudos
Message 10 of 14
(3,720 Views)