LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx producing many system threads

Solved!
Go to solution

Hello-

 

I wrote a VI to collect data off of a NI PCI-6250 card using DAQmx. The VI creates a new task, configures the max/min voltage values and trigger, then collects N data points, and finally closes and erases the task. By itself this VI works perfectly, and I can loop it in Continuous Run mode for extended periods without any problem.

 

However, when I use this data collection VI as a sub-VI in another program something begins generating a new system thread every time the VI is called. These threads never get deleted until the main VI is stopped, so after a few minutes of operation the Windows Task Manager shows several thousand 'dead' threads that have built up but are still taking a slice of the CPU time and the computer slowly grinds to a halt.

 

For the sake of trying to narrow the problem down, I made a VI which is just a while loop wired to never stop and put the data collection VI inside of it with a 250ms wait between iterations. The thread build-up problem exists even for this simple setup.

 

Any suggestions on how to remove these old threads or keep them from forming in the first place?

 

Thanks much!

0 Kudos
Message 1 of 16
(3,238 Views)

Don't create tasks and destroy them in a loop.  Only put the acquisition portion inside the loop.  Put the create task before the loop and the stop/erase task after the loop so that you only do those functions once.

Message 2 of 16
(3,229 Views)

Sounds like you need an Action Engine- Read Ben's nugget

 

Create a AE with four operations (states- defined by a type-def enum with a case for each enum value).

Init- configure your task- save the task on a Shift Register

Read- get your data

Close- Destroy your task.- and clear the Shift rigister

Null- Do nothing but pass the SR contents

 

(Null is a nice operation to have for debugging)

 

Sorry no LabVIEW on this machine or I'd post an example

 

 


"Should be" isn't "Is" -Jay
Message 3 of 16
(3,225 Views)

Thanks for the quick reply. I could do what you suggest, but I'd like to be able to alter the min/max voltage settings from run to run. Right now I'm setting those values when I create the task, and I didn't see a way of modifying them after the task had been set up.

 

Is there a way to change the voltage range on the fly that I just missed when looking through the DAQmx VIs, or will I need to know the min/max values at the start of the measurements and just keep them constant?

 

 

0 Kudos
Message 4 of 16
(3,218 Views)
Solution
Accepted by topic author estiers

You'd do it the same way you are doing now.  You'd close the task and recreate it.

 

However, if you only do it when you need it, (and Jeff's action engine suggestion is the way I'd implement it).  You'd only be doing the creation/closing occasionally rather than repeatedly on every loop iteration of the acquisition.

0 Kudos
Message 5 of 16
(3,212 Views)

Sounds like that's the way to go then. It may produce a few extra dead threads but not at a rate where it will kill the system off after a few minutes of operation. I'll give it a try and see if maybe those few extra threads are able to get closed off when the system isn't running at full tilt collecting data.

 

Thanks to both of you for the quick responses!

0 Kudos
Message 6 of 16
(3,205 Views)

Here is a quick example:

 

I did not create a strict type def of the Enum "Mode"-  You'll want to do that so that if you add an action you can apply changes to update the mode constants throughout your project.

 

Note that I use a property node to set (or read) the AI min and Max voltages without recreating the task

 


"Should be" isn't "Is" -Jay
0 Kudos
Message 7 of 16
(3,197 Views)

One other note is that setting the minimum and maximum only has a practical effect if it results in changing the ADC range on the device.  For instance, on an M Series devices, there is a ±10V range, a ±5V range, and several others.  Changing the minimum and maximum from ±9V to ±8V will both default to 10V, so you should only change the range if it would result in using a different ADC range, otherwise there isn't any benefit.

 

You might try adding an action engine case that uses the DAQmx Control Task VI to uncommit the task, use the Channel property node to update the range, then start the task again.  This way, you don't actually destroy the task and can still change the range.  This should be less resource intensive.

Seth B.
Principal Test Engineer | National Instruments
Certified LabVIEW Architect
Certified TestStand Architect
0 Kudos
Message 8 of 16
(3,191 Views)

estiers,

 

Which version of NI-DAQmx and LabVIEW are you using, and on what operating system?  I'd like to reproduce the behavior you were seeing.

Seth B.
Principal Test Engineer | National Instruments
Certified LabVIEW Architect
Certified TestStand Architect
0 Kudos
Message 9 of 16
(3,174 Views)

>One other note is that setting the minimum and maximum only has a practical effect if it results in changing the ADC range on the device.  For instance, on an M Series devices, there is a ±10V range, a ±5V range, and several others.  Changing the minimum and maximum from ±9V to ±8V will both default to 10V, so you should only change the range if it would result in using a different ADC range, otherwise there isn't any benefit.

 

My goal in switching ranges is to try to preserve as much of the available ADC resolution as possible. The idea is to do a rough initial measurement with the +/-10V range, find the max and min values within that data and then tighten the range to encompass that span plus ~10% on each side. If I can do this automatically it would really be great since it would capture the best resolution possible while being invisible to the average user of the final system.

 

I didn't get a chance to try out the Action Engine idea today, hopefully I'll get some time to work on it tomorrow.

 

 

>Which version of NI-DAQmx and LabVIEW are you using, and on what operating system?  I'd like to reproduce the behavior you were seeing.

 

I've attached a copy of the code in a zip file. The "Collect Data.vi" file reads off of two PCI-6250 cards that are sync'd via an RTSI cable so that the clock and trigger signals are generated by one card and passed to the second card. Running this vi by itself does not seem to cause any problems in terms of generating extraneous threads. The file titled "This one makes threads.vi" simply puts Collect Data into a never ending while loop, and when it is run the Task Manager shows a new thread being generated on every iteration of the loop. After a minute or two you can have thousands of threads.

 

System specs are:

   LabView 8.6

   NI-MAX 4.6.2

   XP SP2

 

Thanks for your interest in this problem, let me know if there is any further information I can provide.

0 Kudos
Message 10 of 16
(3,127 Views)