LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do "sleeps" affect multithreading in LabVIEW Real-Time?

I'm having a problem with my sleep calls in a multithreaded LabVIEW RT application. I tried fixing the problem with no success using the suggestions mentioned in the "Multithreading in LabVIEW Real-Time" article.

http://zone.ni.com/devzone/conceptd.nsf/webmain/D77FD450729E8F02862568EB007533C3?opendocument&node=174826_US

I've attached a small example that demonstrates my problem. The TestRTLoop VI is setup in the "user interface" execution system and runs at "normal" priority. The RealTimeLoop VI is setup in the "other 1" execution system and is to run at "critical-time" priority.

Time should increment by 1000 ms, but instead it's incrementing by 2000 ms. It's like when this VI sleeps, it caus
es the real-time loop to also go to sleep. But this doesn't always hold true. If I change the sleep time in this VI to be 999ms, the program works as expected. If I change the sleep time to be 2000ms, the timer still increments by 2000ms rather than 3000ms.

Any help is greatly appreciated.
0 Kudos
Message 1 of 5
(3,457 Views)
Hi Coryvan,

I don't have time to look at your code but let me guess that you are using the "wait until next...".

If so try using the "wait" instead.

What is probably happening is that the code takes just over 1ms to execute. This means that you are missing the multiple you are trying to sync with, and the code ends up missing the first multiple and has to wait for the next.

I hope this helps,

Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 2 of 5
(3,457 Views)
Hi Ben,

Thanks for the reply.

Your right that I'm using the "wait until next" VI in both my user interface loop and my real-time loop. Your answer would make sense to me if I was changing the sleep time in the real-time loop, but I'm only changing the sleep time in the user-interface thread. Why does changing the sleep time in the UI thread affect the amount of time that the real-time thread sleeps when I don't change a thing in there?

Also, I don't think I want to change to the "wait" VI in my real-time loop because I need to maintain determinism in this loop. The "wait" VI may cause my loop to sleep different amounts of time if the amount of processing varies from iteration to iteration.

But thanks to your advice, I have a new theory here. I
changed the "wait until next" VI in the UI loop to be just a "wait" VI. I kept the "wait until next" in the real-time loop. This seemed to fix my problem. My guess is that the RT development environment makes the assumption that loops with the "wait until next" VI are time-critical. This would cause me to have two time-critical loops (the UI and the RT loops). According to the NI article referenced above, this could cause both threads to sleep if one sleeps.

Now that I think about it, this can't be entirely correct either. The NI article says that if the two critical threads are in different execution systems, they don't affect one another. Mine are in different executions systems, but somehow they are still influencing each other. Any thoughts?

But hey, thanks for your help. I think we got a work around that will be good enough for my app. Have a good day.
0 Kudos
Message 4 of 5
(3,457 Views)
I'm not sure if everyone will be able to run the files I attached previously as there were a few VIs used in there that are not part of the standard LabVIEW VI library. Here's an updated attachment that should include everything you need. The top-level VI is named "TestRTLoop.vi".
0 Kudos
Message 3 of 5
(3,457 Views)
The problem is that you are using a 3rd party "Wait Until Next ms Multiple" function (green VI) as opposed to the yellow LabVIEW primitive that appears in your functions palette. I agree that it would be nice if the LabVIEW primative had an error cluster to make forcing the order of execution easier, but there are two solutions to your problem:

1. Replace the green VI you are using with the yellow LabVIEW primitive.

2. Open the green VI. Go to the place where you would set priority and execution system. Set the VI to reentrant, click OK, and save.

Either method works fine for me. What is happening is that when the VI is not reentrant, it can only be executing once at any given point in time. It looks like the normal priority loop is still using it wh
en the RT one wants to, or vice versa. Making it reentrant causes there to be as many copies of it in memory as there are uses of the VI in the block diagram. This of course uses more memory if the VI is called in many places, but it can be useful.

Jeff B
National Instruments
Message 5 of 5
(3,457 Views)