From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Realtime, semaphores, and subvi's

Solved!
Go to solution

Hi,

 

We use a handful of semaphores in our (2015) Realtime app on a cRIO.  For cleanliness, I wanted to encapsulate each semaphore in their own VI.  When I did this the semaphores didn't function correclty.  I feel like there's a basic tenet of labview that this uncovers, and I need to know it!

 

So below is more or less the standard semaphore HelloWorld program - it's similar to the Labview Simple Semaphore.vi example.  The "Numeric" and "Numeric Slow" indicators increase more or less in lockstep.

 

sem1.png

 

 

The next thing I did was create a VI to perform the Acquire and Release semaphore functions, as shown below.  You may ask "What's the point?".  Well, in my desired version of the VI the semaphore would not be a Control and instead would be "Obtained" within the VI (and thus avoiding passing the semaphore throughout our program).  For this posting (and test) I wanted to make things as simple as possible so I pass in the semaphore.  Note that the VI is non-reentrant, making it single threaded.

 

sem2.png

 

 

Using the VI in the test program is shown below (in a disabled state)

 

sem3.png

This doesn't work!  I've traced the program and the Acquire works (one thread proceeds and the other blocks), but the Release (on the 'Acquired' thread) hangs.  Looking into the Labview Release Semaphore.vi code I don't see a reason it would block (I can't add breakpoints or probes to this code).

 

Can someone make sense of this for me?

 

Thanks,

Steve

 

 

 

0 Kudos
Message 1 of 6
(4,181 Views)

What does your test do if you don't diagram disable all of the functional code?

0 Kudos
Message 2 of 6
(4,177 Views)
Solution
Accepted by topic author maherhome

I've made this same mistake with an Action Engine using queues.

 

Your problem is that only 1 call to the subVI can happen at a time.  So you have one thread acquire the semaphore through the subVI.  During that time, the other thread is waiting to be able to use the subVI to acquire the semaphore as well.  So the first thread completes the subVI sucessively and does its task.  Meanwhile the other thread is stuck in the subVI waiting for the semaphore to be released.  Now the first thread is done with its task and tries to go into the subVI to release the semaphore, but it can't since the second thread is still using the subVI.  So the second thread is blocking the first thread from using the subVI and the first thread is blocking the second thread by not being able to release the semaphore.  You are in a deadlock.

 

Why are you using semaphores anyways?  I have found that they are rarely needed in a properly modulated code.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 3 of 6
(4,172 Views)

Hi,

 

Sorry to be confusing.   When the disabled code is enabled and run, the Acquire works (one loop]proceeds and the other blocks), but the Release (on the 'Acquired' thread) hangs.  The indicators remain at 0 and 0.    Not that it matters, but I think the bottom loop typically acquires the lock when I run.

 

Steve

0 Kudos
Message 4 of 6
(4,169 Views)

Crossrulz,

 

Thanks - makes sense!  Can't have locks on a lock API 😃   I was lulled a bit because we use this paradigm for semaphores in our FPGA code (using VI-scoped FIFOs in sub VIs).  I think that gets flattened and dealt with in a completely different way.

 

Why semaphores? We have a 3 DMA cRIO and are restricted to a single DMA for pumping out a large variety of data from far flung parts of our large FPGA design.  A semaphore is used to ensure that multiple bytes written by (possible simultaneous) DMA writers remain contiguous.  It works well.

Steve

0 Kudos
Message 5 of 6
(4,160 Views)

Oops, I should have said more ... We are using semaphores on the RT side for a similar reason: far-flung data producers writing to a single queue to be pumped out a TCP port.   The data types are varied so we flatten everything to bytes.

 

Steve

0 Kudos
Message 6 of 6
(4,156 Views)