LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Semaphores and queue together. Is it necessary?

Hello.

 

I am using a State Machine driven by queue, using a For Loop to enqueue three States that have to be executed in sequence. The code is working fine but when I run it in Highlight Mode is possible to see that the "State 1" of the State Machine start running while the For Loop (which enqueue the elements) is still running. Is this kind of code safe?

 

I mean, for this example everything is working fine, but if I have SubVIs running in the States of the State Machine, would not be safer to have the For Loop execution done, before start playing with the SubVIs of the State Machine? Would a semaphore help me with that? I found this thread that discussed similar things, but I still thing that would be safer to have the For Loop done and just after that start running the State Machine.

 

What do you thing guys?

 

Thanks

 

Dan07

 

Screen.jpg

Message Edited by dan07 on 04-17-2010 02:59 AM
0 Kudos
Message 1 of 41
(4,098 Views)

I mistyped.

 

thing=think

 

Sorry

 

Dan07

0 Kudos
Message 2 of 41
(4,088 Views)

You can use a semaphore to protect a section of code from running until another section of code allows it.  But why do you need to do that?  You talk about "is this kind of code safe".  Safe from what?  Is there some kind of process you are trying to control that would cause a safety hazard if you have state 1 starting before you've put state 2 into the queue?

 

I've used queues numerous times.  I've used state machine numerous times.  I don't think I have yet to use a semaphore in a real world application.

0 Kudos
Message 3 of 41
(4,057 Views)

For example: the idea is to run State 1, State 2 and Idle after I click the RUN button. Nevertheless, if inside the State 1 there is a SubVI that will evaluate the current time of the day. If the time is something between 2:30 pm and midnight, its necessary to run State 2 after the State 1, so, it's not necessary to change anything in the Queue. But if the time is not in this range, it's not necessry  to run State 2 after State 1 and the SubVI inside State 1 must use the Flush option to clean the Queue totally. If I have the State 1 done and the SubVI evaluates that is not necessary to run State 2, it will try to Flush and clean the Queue totally, but the Queue is still been created inside the For Loop. In this situation a semaphore would help a lot. Am I right?

 

I don't have experience working with semaphores, could you show me a simple way to implant them in my code?

 

Thanks

 

Dan07

0 Kudos
Message 4 of 41
(4,045 Views)

Good question dan!

 

The code you are explaining is "SAFE".  and seems like a good implementation of a basic "Producer-comsumer archetecture"  Your UI stays responsive while the consumer loop does all the data manipilations.  A very positive point.

 

I am a bit concerned about scaleability of the code since you have added a programatic "flush queue" in the consumer loop.  It does what you want today but, what if you add a state that enters from another event?  the flush queue tosses that element out too.  Smiley Sad and you might really want to do what the operator asked.  I would do the time check in the producer loop (not much code to slow things down - just a timer call and a comparison right?) and determine if its correct to queue up the time based state(s).

 

Then again- I'm struck with the need for a time enabled state-  will the operator expect the code to behave differently at different times?   It is possible but, questionable. 

 

By-the way.

you can exit the consumer loop based on the error out of the dequeue element.  it returns when the queue is destroyed or when there is an element.

Message Edited by Jeff Bohrer on 04-17-2010 03:39 PM
Message Edited by Jeff Bohrer on 04-17-2010 03:41 PM

"Should be" isn't "Is" -Jay
Message 5 of 41
(4,037 Views)

The evaluation of the time of day was just an example. What really happens inside the State 1 is a code that will open a File Dialog and allow the user load a ascii file. Nevertheless, if the user closes the File Dialog the "open file operation" is cancelled and is no longer necessary to run State 2. This is the real situation. I would like to use the producer loop just to enqueue elements and not do any kind of evaluation or operations inside it.

 

I did a very simple test. I got the VI that I attached to the first message of this thread and put a Flush Queue inside State 1 and executed the VI in Highlight Mode. At the time that the State 1 flushed the queue, it was able to flush the State 2 out, but not the Idle. So, even with the Flush operation the Idle case was executed after State 1. I know that in the real speed execution, the enqueue operation of the For Loop is very very very fast and even if the user closes the File Dialog quickly, the whole enqueue operation by the For Loop would be done at that time. But, I think that is dangerous to let the code like that with the assumption that the For Loop will be always faster than the action of the user closing the File Dialog.

 

Because of that, I would prefer to add a semaphore to make sure that the whole enqueue operation by the For Loop would be complete, before the State 1 start running. What is the best design for the semaphore code you think best applies for this code?

 

Thanks

 

Dan07

Message Edited by dan07 on 04-17-2010 04:05 PM
0 Kudos
Message 6 of 41
(4,032 Views)

I forgot to say that since I put the Flush operation inside State 1, I had to put the Queue wire into a Shift Register in the Consumer While Loop.

0 Kudos
Message 7 of 41
(4,023 Views)

You can enqueue states from inside the consumer loop as well.  If in the process of state 1, you decide you need to run state 2, then let state 1 enqueue it.  Maybe it decides to enqueue a state 3, or not enqueue the next state at all.

 

Don't enqueue states just because you think you may need them, add them when you know you do, wherever that may be from.  The data you enqueue could not only contain what state you want to run, and of course any data that goes with it, but also contain what state you want to run after that in the event that state 1 "passes", and perhaps another piece of data that is the state you want to run after that in the event that state 1 "fails".

Message 8 of 41
(4,009 Views)

Ravens

 

I've been adding some new elements to my state machine and because of that I am trying different approaches to make the code as clean as possible. I was doing some enqueue inside the consumer loop, but right now I am considering let this job for the producer loop only.

 

Could you add a basic semaphore code to my VI? Because with that I can be sure that the for loop will executes first, and then the consumer loop will run.

 

Thanks

 

Dan07

0 Kudos
Message 9 of 41
(3,994 Views)

Obtain the Semaphore reference before both loops and release the reference after both loops.

 

Acquire the semaphore before the For Loop in you producer, and release it after the For Loop.

Acquire the senaphore after the Dequeue function in the consumer, and release it after the state is done.

Message 10 of 41
(3,969 Views)