LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What threads are used during usual VI execution?

I am trying to understand how UI thread is interacting with other threads in LabVIEW.

 

So the first thing is what are the "other threads"? I found this article. So for simplicity let's assume I have Windows 7, a single processor, one core and no ActiveX. When an application starts I would have 23 threads running, namely:

  1. user interface thread
  2. standard execution system (normal) thread
  3. standard execution system (above normal) thread
  4. standard execution system (high) thread
  5. standard execution system (time-critical) thread
  6. instrument I/O execution system (normal) thread
  7. instrument I/O execution system (above normal) thread
  8. instrument I/O execution system (high) thread
  9. instrument I/O execution system (time-critical) thread
  10. data acquisition execution system (normal) thread
  11. data acquisition execution system (above normal) thread
  12. data acquisition execution system (high) thread
  13. data acquisition execution system (time-critical) thread
  14. other 1 execution system (normal) thread
  15. other 1 execution system (above normal) thread
  16. other 1 execution system (high) thread
  17. other 1 execution system (time-critical) thread
  18. other 2 execution system (normal) thread
  19. other 2 execution system (above normal) thread
  20. other 2 execution system (high) thread
  21. other 2 execution system (time-critical) thread
  22. timer 1 (for LabVIEW internal use)
  23. timer 2 (for LabVIEW internal use)

In addition to this, from what I understand, more threads can be created if my code can be split into "clumps". Maximum number of clump threads per execution system priority thread can be configured in C:\Program Files (x86)\National Instruments\LabVIEW 20XX\vi.lib\Utility\sysinfo.llb\threadconfig.vi.

 

If that part is correct, I would like to ask about the interaction between UI thread and other execution systems.

 

In this, I found: "There are several different types of threads that LabVIEW allocates: One user interface thread, used for screen drawing and keyboard/mouse input. This thread is also used for certain types of VI execution, such as property nodes, thread-unsafe CINs, and DLLs, etc.".

 

Lets now assume we have simple VI configured to run in default configuration which is Standard execution system with Normal priority. The VI is while loop with a stop button connected to a conditional terminal (stop loop). Inside the loop we have a random number generation with output connected to numeric indicator. No additional clump threads, because the code is simple.

Random Number.viRandom Number.vi

When I run it, from all the 23 threads only 2 will take part in the execution. More or less what will happen:

  • random number generation will be called and the result will be moved to the numeric terminal. all in the standard-normal execution system.
  • the standard thread will be switched and UI thread will become active
  • indicator value update will be drawn on the screen
  • threads will be switched back to check loop termination condition
  • and again to random number generation and we have a loop

When I click on a stop button it will be registered in UI thread and somehow moved to the terminal which is a part of the diagram which is a part of the standard execution system.

 

So the interaction between threads will look like on this pseudo code:

Threads interactionsThreads interactions

Is this more or less correct?

 

What I was not able to find:

  1. When threads are actually switched?
  2. When the screen is updated?
  3. How block diagram terminals are updated when a user e.g. clicks on the front panel button?

Thanks for the help.

Michał Bieńkowski
CLA, CTA

Someone devote his time to help solve your problem? Appreciate it and give kudos. Problem solved? Accept as a solution so that others can find it faster in the future.
Make a contribution to the development of TestStand - vote on TestStand Idea Exchange.
0 Kudos
Message 1 of 6
(2,464 Views)

Just a quick reply..

 

I the indicator (numeric) is NOT marked a "synchronous" the switch to the UI thread is not required. LV will update the indicator when it wants to do so and not stall the loop thread.

 

I believe the desk Trace Execution Toolkit will offer insight if you want to poke at to learn more.

 

LV uses the OS to schedule threads so the exact time threads are switched is an OS question.

 

Done with the quick replies.

 

Q for you!

 

What is prompting you to ask these questions?

 

Is there something specific we can help you figure out?

 

Ben

 

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 2 of 6
(2,435 Views)

@bienieck wrote:

 

When I run it, from all the 23 threads only 2 will take part in the execution. More or less what will happen:

  • random number generation will be called and the result will be moved to the numeric terminal. all in the standard-normal execution system.
  • the standard thread will be switched and UI thread will become active
  • indicator value update will be drawn on the screen
  • threads will be switched back to check loop termination condition
  • and again to random number generation and we have a loop

What you don't show is that there is additional buffering. The controls and indicators have what is called a "transfer buffer", so after your random number reached the indicator, it will be written to the transfer buffer so the code can continue immediately. At leisure, the UI thread comes along and copies the data from the transfer buffer to the indicator which maintains yet another copy of the data. A good rule of thumb is that you'll typically have a minimum of three data copies if a front panel object is involved (immediate wire value, transfer buffer, indicator).

 

Your greedy loop is probably a bad example. Why not add a measurement of the actual loop time? (Yes, if you would change the indicator to synchronous (right-click...advanced...synchronous display), you would see a gigantic loop slowdown because it would do what you described instead! ;))

 

If you would place two of these loops on your diagram, things get even more complicated. If there is no wait, LabVIEW will spin each loop many times before giving the other loop a slice of the pie (assuming one cpu core overall. Modern processors have several cores, so things get more generous and complicated). If you would place a 0ms wait, the two loops would alternate yielding to the other after each iteration. For an old demo, have a look at this code (posted here about 11 years ago)

 

I think while LabVIEW simply generates all these thread, the OS is responsible for the scheduling.

 

Also remember that DFIR/LLVM might do a lot of optimizations and rearranging, so the actual code might not have much resemblance to what you wired ;)) Things might even change between LabVIEW versions.

 

I agree that Ben's question seems important: What are you actually trying to solve???

The compiler team did a fantastic job ensuring that we don't really need to worry about any of this, and even if we would worry, there is little we can do about it. 😉

Message 3 of 6
(2,411 Views)

Here you can see that the difference between synchronous and asynchronous display of a single numeric indicator can cost up to four orders of magnitude more.

 

syncasync.png

Message 4 of 6
(2,407 Views)

Thank you all for your time and responses.

 

In response to this: "I agree that Ben's question seems important: What are you actually trying to solve???

The compiler team did a fantastic job ensuring that we don't really need to worry about any of this, and even if we would worry, there is little we can do about it."

 

I'm not trying to solve any particular problem. I just like to know how things work. The whole question appeared in my mind after reading about the root loops http://www.labviewcraftsmen.com/blog/the-root-loop

 

There is this example demonstrating how UI thread can be blocked by e.g. timestamp control (I have attached VI to play with this case). However, I do not get it. Screen redraw suppose to be performed in UI thread and setting date in timestamp control should block this thread (as in the example with property node in the mentioned article). What I understand, if UI thread performs redraw, it is unavailable for other tasks, but timestamp requires UI thread as well. So how can FP be updated while timestamp "set date window" is on?

 
Michał Bieńkowski
CLA, CTA

Someone devote his time to help solve your problem? Appreciate it and give kudos. Problem solved? Accept as a solution so that others can find it faster in the future.
Make a contribution to the development of TestStand - vote on TestStand Idea Exchange.
0 Kudos
Message 5 of 6
(2,386 Views)

While they may seem related the Root Loop and the UI thread are not the same thing.

 

In my own words...

 

The Root Loop is what handles mapping LV code into memory doing Mallocs and such to to allocate memory and load the LC binary into memory. It is invoked when dynamically loading VIs since it has to stop everything while run in Kernal mode (see task manager >> Performance >>> Show kernel times)

 

THe UI thread is used for GUI updates (since those updates can come from anywhere and have to be coordinated to support overlapping indicators graphs etc) and is implemented as "single threaded". AS such it is safe place to do stuff like running non-thread-safe dll and poking as thread resources like property nodes.

 

Tying up the Root Loop or the UI thread will inhibit GUI updates but for different reason. In the case of the former we are running in Kernal mode (used by the OS to OPERATE the hardware) and the latter to keep the GUI consistent.

 

For more reading that required duct tape for safety purposes you can review this post I shared after squeezing LV support until they finally gave up and answered my question about VI server and re-using buffers.

 

Re: The Time Stamp control

 

I reported that as a bug and its behavior was changed a few releases back.

 

 

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 6 of 6
(2,376 Views)