LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Multi-Threading sub-VI's

Hello,

I was wondering what is the best way to make a sub-VI launch without having
the parent VI to wait for it to stop... in other words, launching it in a
separate thread. I need this scheme so I can launch this same SubVI a
number of times... all running at the same time. Doing while loops and
indicating the subVI's to be reentrant does me no good. Can anybody out
there show me the correct path to take.

Thank you in advance.

John
0 Kudos
Message 1 of 9
(7,132 Views)
> I was wondering what is the best way to make a sub-VI launch without having
> the parent VI to wait for it to stop... in other words, launching it in a
> separate thread. I need this scheme so I can launch this same SubVI a
> number of times... all running at the same time. Doing while loops and
> indicating the subVI's to be reentrant does me no good. Can anybody out
> there show me the correct path to take.
>

If you are interested in having these parallel running subVIs execute without
their panel being open, then you can make the subVI definition
reentrant, and
then you can do the parallel while loop, which will allow for reentrant
execution. This will still synchronize with the top level VI, as all
subVI calls
are synchronous. If you want to make an asynchronous call, then you
will want
to use the VI Server. The Call by Reference node will still make synchronous
calls, but easily allows for parameters.

The way to make asynchronous calls is to Open a reference to the subVI
and call
it using the Run method with the invoke node. This is pretty much the
same as
pressing the Run button on the referenced VI. The node has an optional parameter
that determines whether it waits for execution to complete or returns immediately.
The immediate return is what you want. Note that it is a bit more
complicated to
pass parameters using the Run method. There are other methods for
reading and
writing controls, but again it is more complicated than just wiring to a subVI.

Another couple pointers in using the Run method. If you want the launched
subVI to continue running even if the top-level caller exits, then have the
subVIs open a second reference to themselves. They will stay open until all
references are released. If you want each of these references to have
their panel open, then this technique will not work, as LV doesn't currently
allow for multiple panel instances for a single VI. The alternative
there is
to make copies of the subVI in the temp directory and open those using the
VI Server and use the Run method on those. Each of the copies can have their
own panel open. This is definitely a workaround, but quite a few customers
have used it to get around this limitation.

Greg McKaskle
Message 2 of 9
(7,132 Views)
In article <38757DB3.C218C67@austin.rr.com>,
gmckaskle@austin.rr.com wrote:
> > I was wondering what is the best way to make
a sub-VI launch without having
> > the parent VI to wait for it to stop... in
other words, launching it in a
> > separate thread. I need this scheme so I can
launch this same SubVI a
> > number of times... all running at the same
time. Doing while loops and
> > indicating the subVI's to be reentrant does
me no good. Can anybody out
> > there show me the correct path to take.
> >
>
> If you are interested in having these parallel
running subVIs execute without
> their panel being open, then you can make the
subVI definition
> reentrant, and
> then you can do the parallel while loop, which
will allow for reentrant
> execution. This will still synchronize with
the top level VI, as all
> subVI calls
> are synchronous. If you want to make an
asynchronous call, then you
> will want
> to use the VI Server. The Call by Reference
node will still make synchronous
> calls, but easily allows for parameters.
>
> The way to make asynchronous calls is to Open a
reference to the subVI
> and call
> it using the Run method with the invoke node.
This is pretty much the
> same as
> pressing the Run button on the referenced VI.
The node has an optional parameter
> that determines whether it waits for execution
to complete or returns immediately.
> The immediate return is what you want. Note
that it is a bit more
> complicated to
> pass parameters using the Run method. There
are other methods for
> reading and
> writing controls, but again it is more
complicated than just wiring to a subVI.
>
> Another couple pointers in using the Run
method. If you want the launched
> subVI to continue running even if the top-level
caller exits, then have the
> subVIs open a second reference to themselves.
They will stay open until all
> references are released. If you want each of
these references to have
> their panel open, then this technique will not
work, as LV doesn't currently
> allow for multiple panel instances for a single
VI. The alternative
> there is
> to make copies of the subVI in the temp
directory and open those using the
> VI Server and use the Run method on those.
Each of the copies can have their
> own panel open. This is definitely a
workaround, but quite a few customers
> have used it to get around this limitation.
>
> Greg McKaskle
>


I've used the VI server approach and it works OK,
but when I "compile" the application for
distribution, the VI search window pops up trying
to find the VI that the call reference is
addressing, does anybody know the way around this
without having to install labview on the end
user's machine.

Leopoldo Pena


Sent via Deja.com http://www.deja.com/
Before you buy.
0 Kudos
Message 3 of 9
(7,132 Views)
....
>
> I've used the VI server approach and it works OK,
> but when I "compile" the application for
> distribution, the VI search window pops up trying
> to find the VI that the call reference is
> addressing, does anybody know the way around this
> without having to install labview on the end
> user's machine.
>

When you redistribute an application, be sure to take
the dynamic VIs with you. The application builder
doesn't know which dynamic VIs you will use; so it is
up to you to take them along. also, when you refer to
the dynamic VIs, you are providing some path. Is that
path valid on the new machine? If it is a constant
full path that specifies the driver number and all, then
it won't work very well on various computers. You may
want to m
ove the dynamic VIs so that they are in the
same LLB or near the top-level VI, in a subfolder, so
that you can construct the path. There are constants
in the file I/O palette that will give you the LV
directory and this VIs directory. You will probably
need to use the Strip Path VI to take off the VI name,
and perhaps another level, then use Build Path to add
on the directory names and the dynamic Vi name.

Greg McKaskle
0 Kudos
Message 4 of 9
(7,132 Views)

I am also just getting started with multi-threading in LabView, and have read whatever material from NI that I can find about the topic. Can someone give some clarity about how multithreading is implemented in code? There are two separate VIs that I would like to run in parallel as different threads.

Here is what I implemented:

- created subVIs which are separate VIs that run perfectly

- placed both subVIs in a "master" VI which calls both

 

ooyeniyi_0-1621544498880.png

 

My questions are:

- is this how multi-threading is implemented?

- how can I prove that the threads are indeed on separate threads?

- how can I determine which thread is being executed at any given time?

- is the While Loop necessary? (only included it to create a form of partition. Would it still be multi-threading if the loops were replaced with frame structures instead, or perhaps nothing at all?)

0 Kudos
Message 5 of 9
(3,184 Views)

LabVIEW is always executing things in parallel. The way it operates is that the compiler breaks things down to nodes which can execute. When a node is ready to run, it will be exeuted. For example, in the code you posted the compiler will consider each while loop a node. It will further break things down and start to identify the nodes which are inside each while loop. In your case, this is each of your subVIs. It will then analyze everything inside the subVIs and so on until it reachs the most primative nodes such as the add or subtract functions. A node is capable of running if all of its inputs are available. Outputs from a node do not exit the node until the node has fully excuted. So, a subVI can execute once all of its inputs are available. This is how multiple things can run in parallel within LabVIEW. It is also the foundations of dataflow programming. The wires that connect your code will dictate the execution order. If two nodes do not have any data dependency between them they both can execute in parallel. Therefore in your code example the two while loops will execute in separate threads in parallel. LabVIEW is also smart enough to execute different sectionsof code on different processors giving you better overall performance. This is one of the most excellent things about LabVIEW is that it takes care of executing things in parallel and in multiple threads. Unlike most traditional text based languages you don't have to concern yourself with creating threads and processes. The language handles that for you.

 

That doesn't mean however that you don't have to thinnk about your code and how it is written. You need to consider race conditions because the code does run in parallel and in separate threads. This is why it is advised that you don't use local/global variables. Use the wires to transfer data. Or when you get more experienced you can use queues, notifiers or other more advanced features.

 

In terms of how to know what will execute when, with the exception of the dataflow there is no gaurantee of the order of execution. Therefore, if you have nodes which do not have a data dependency between you should not expect a specific order of execution. It is best to assume they will execute at the same time. So if you need to enforce order of execution use the dataflow. Avoid using sequence structures.

 

With respect to your question about whether the while loops are necessary, without knowing what is in the subVIs it is impossible to say. Generally though your code will have some loops so it can execute continuously. Where those loops are depends on the architecture you choose. In most cases the top level VI (the "main" of your application) will have at least one loop. Large applications can have multiple concurrent state machines running so there will be lots of loops. You just won't see them all on the block diagram. At least not if it is a well written application. Initalization code will spawn the various state machines that are required or they can even be started dynamically during execution. They may run for the duration of the application or only brief moments to accomplish a specific task and then exit.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 6 of 9
(3,174 Views)

Thanks for the detailed response, Mark. I need to think about the points you made.
Can you point me in the direction of an example of Multithreading in LabView? Some things would become more obvious if I can see prior implementation. Most of the examples that I have seen use While loops, and are not well explained.

0 Kudos
Message 7 of 9
(3,127 Views)

You could look at examples of the Producer/Consumer architecture. They generally have two loops running. The other thing you could look at are the examples of calling VIs dynamically using the "Start Asynchronous Call".



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 8 of 9
(3,122 Views)

@ooyeniyi wrote:

There are two separate VIs that I would like to run in parallel as different threads.

...

- is this how multi-threading is implemented?

- how can I prove that the threads are indeed on separate threads?

- how can I determine which thread is being executed at any given time?

- is the While Loop necessary? (only included it to create a form of partition. Would it still be multi-threading if the loops were replaced with frame structures instead, or perhaps nothing at all?)


LabVIEW does not create a dedicated thread for each subVI, in fact, LabVIEW creates many threads which are shared among all parts of the code. One thread is the UI thread that handles the front panel. LabVIEW is excellent at balancing the workload and threads.

 

Start reading here.

 

Now to the other questions:

  • Start reading about the LabVIEW compiler. It is fantastic!
  • Not sure what the question is. Seems circular.
  • Modern computers have multiple CPU cores, so several thread can execute in parallel.
  • The while loop is necessary if you want to repeat the code over and over. Do you? What do the subVIs do? Do they return quickly or lock the caller forever? What is the desired loop rate (you have no defined timing!)
  • I am not familiar with a "frame structure" is this a programming structure or a decoration?

Are you trying to solve any specific problem? Do you need help programming? I recommend to start a new thread, attach simple example code, and ask detailed questions.

0 Kudos
Message 9 of 9
(3,083 Views)