LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

System Exec.vi "Wait Until Completion" uses a Lot of CPU. HELP

Solved!
Go to solution

I am writing an application that calls parallel instances of an external program. I have working code to run the EXE with the System Exec.vi. When the Wait Until Completion input is set to true on the System Exec.vi LabVIEW uses all my CPU. The EXE I'm running is a low intensity exe and if I don't wait until completion LabVIEW does not have high CPU usage. This would be fine but I have code that needs the EXE to finish before moving on. Am I doing something wrong? I couldn't find this behavior as a known issue so I would like a sanity to make sure I'm not making any dumb mistakes. I have attached a demo that recreates the issue. The VI calls the EXE with Launches notepad and then updates the notepad text. I have attached the source code for the demo EXE as well.

 

Download All
0 Kudos
Message 1 of 7
(2,498 Views)

Well, the problem is that your routine, Waiting, actually waits (and hence blocks any other code from running) until all of the launched instances of NotePad finish.  If the "greater logic" of your routine is that you have to launch 20 instances of NotePad and wait for them to all signal they are done before you do anything else, you are stuck (unless you can do whatever without NotePad).

 

On the other hand, if you can launch 20 NotePads, do some things in LabVIEW that don't require NotePad to have finished, then when you need NotePad to finish, do the Wait, I've got some suggestions.

  • Create two sub-VIs, one that Launches NotePad and a second that Waits for NotePad.  Now you can Launch, Do Other Things, Wait, and Do Final Things.  If your "Do Other Things" code gives you enough time for NotePad to have Done Its Thing, then when you call the Wait routine, it will return immediately.  [Note you probably want to parameterize the sub-VI if you want multiple NotePads running].
  • I don't know if calling NotePad using SystemExec causes it to run "in series" or "in parallel" with the calling routine.  You can force it to run "in parallel" (which is really what you want it to do) by running the Launch VI using Start Asynchronous Call (and Return).  If you do this, you can safely combine the original Launch and Wait VIs mentioned abovve to be a single "Run NotePad" VI that waits for itself to finish and then exits.  You need to set up Start Asynchronous Call as a "Call and Return", then have an "Is NotePad Done?" routine do a Wait on Asynchronous Call.  Use a short Timeout, and if it returns an Error (meaning Notepad is still running), clear the Error, wait, say, a second, and try again.

Bob Schor

 

0 Kudos
Message 2 of 7
(2,480 Views)

Thank you Bob

 


Waiting, actually waits (and hence blocks any other code from running) until all of the launched instances of NotePad finish. 


In my case I am running a command line executable "Idel_EXE.exe". This executable is responsible for running under the hood tasks. In the demo it is supposed to Launch an instance of notepad, or perform an Idle process on notepad. My LabVIEW application runs instances Idel_EXE.exe" witch performs independent tasks and I do want to wait until all the instances of "Idel_EXE.exe" are done. LabVIEW sequentially launches 20 instances of "Idel_EXE.exe" that launch a notepad and returns information. Then LabVIEW launches 20 parallel instances of "Idel_EXE.exe" that each performs an operation on the notepad handle passed in. But when the parallel for loop finishes the LabVIEW application CPU jumps to 100% if I have System Exec Waiting enabled.

 

The architecture is a lot like your second built point but instead of Asynchronous calls to VIs it is calls to "Idel_EXE.exe"

0 Kudos
Message 3 of 7
(2,475 Views)
Solution
Accepted by topic author Brandon.Baxter

@Brandon.Baxter wrote:

Thank you Bob

 

LabVIEW sequentially launches 20 instances of "Idel_EXE.exe" that launch a notepad and returns information. 

 


That description is exactly what Asynchronous Call and Collect is supposed to handle.  The "Call" processes only the Controls, passing the data "in" to the VI you are calling.  The "Wait on Asynchronous Call" does the rest -- if the Called VI has finished and wants to pass data "out", this function provides the values.  As I noted, if the called VI is still running, Wait Asynchronous can time out, returning an Error (which you can use as a "Wait a little longer" signal).

 

 

Bob Schor

0 Kudos
Message 4 of 7
(2,464 Views)

Asynchronous calling the System Exec VI was able to produce the same intentional behavior of my old VI without the CPU spike at the end. Thanks again Bob! I am still unclear as to what cause the CPU spike though. Both VIs essentially do the same thing I call the System Exec VI with the same for loop but now the System Exec VI is wrapped in an asycronys call. in both implementations the System Exec VI start and end at the same time so where did the extra CPU usage come from?

0 Kudos
Message 5 of 7
(2,445 Views)

This solved the CPU spike in my demo but the issue still exists in my project. I'm essentially making a class that will be use to interface LabVIEW with Functions present on an external AutoIt command line executable. For some reason when I call parallel instances of the command line exe LabVIEW gets into some odd state and hogs all the CPU. I have isolated the issue to parallel calls of System Exec.vi. Your solution worked for the recreated example but I'm thinking it may be some bug in LabVIEW 2014. What version of LabVIEW are you running and do you see the CPU jump of does the VI run smooth?

0 Kudos
Message 6 of 7
(2,439 Views)

I've never tried running multiple copies of SystemExec, so I can't directly address your question.  However, I've definitely implemented "Run multiple copies of this VI simultaneously" using Asynchronous Call as far back as LabVIEW 2010 and as recently as LabVIEW 2016 (with Channels, even).  Another advantage of the Asynchronous Call method is that if you use Strictly Typed Static VI References and a VI Path Property Node to build the VI References needed for Start Asynchronous Call, the exact same code works in both Development Mode and when compiled as an Executable.

 

Bob Schor

Message 7 of 7
(2,422 Views)