Admin Production ni-theme
Current Publication

Using a Thread Pool to Run Code

LabWindows/CVI

Using a Thread Pool to Run Code in Secondary Threads

The purpose of the thread pool is to handle creation and caching of a set of threads, which reduces the amount of time your program spends creating and destroying threads. The thread pool runs your function, which is called a thread function, in one of the threads that it is managing. Instead of calling a function from your program's main thread or creating a new thread to execute the function, you can schedule your thread function with a thread pool. Depending on the configuration and current state of the thread pool at the time you schedule your function, the thread pool creates a new thread in which to run your function, uses an existing idle thread to run your function, or waits until an active thread is finished and uses it to run your function.

The Utility Library provides a default thread pool. You cannot specify callbacks for or set the attributes of the default thread pool.

The default thread pool is configured as follows:

ATTR_TP_THREAD_STACK_SIZE: 0 (the size is set to the size of the creating thread's stack)

ATTR_TP_THREAD_SECURITY: NULL (child processes cannot inherit thread handles)

ATTR_TP_PROCESS_EVENTS_WHILE_WAITING: TRUE

ATTR_TP_THREAD_PRIORITY: THREAD_PRIORITY_NORMAL

ATTR_TP_MAX_NUM_THREADS: 2 + (2 * (number of processors))

You can use the CmtNewThreadPool and CmtSetThreadPoolAttribute functions to create a new thread pool and customize its properties.

Example Code

The following code shows how you use CmtScheduleThreadPoolFunction to execute, in a secondary thread, a thread function that performs data acquisition.

int CVICALLBACK DataAcqThreadFunction (void *functionData);
int main(int argc, char *argv[])

{

int panelHandle;
int functionId;

if (InitCVIRTE (0, argv, 0) == 0)

return -1; /* out of memory */

if ((panelHandle = LoadPanel(0, "DAQDisplay.uir", PANEL)) < 0)

return -1;
DisplayPanel (panelHandle);
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, DataAcqThreadFunction, NULL, &functionId);
RunUserInterface ();
DiscardPanel (panelHandle);
CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionId, 0);
return 0;

}

int CVICALLBACK DataAcqThreadFunction (void *functionData)

{

while (!quit) {

Acquire(. . .);
Analyze(. . .);

}

return 0;

}

In the preceding code, the main function call to CmtScheduleThreadPoolFunction causes the thread pool to create a new thread to execute the DataAcqThreadFunction thread function. The main thread returns from CmtScheduleThreadPoolFunction without waiting for the DataAcqThreadFunction function to complete. The DataAcqThreadFunction function executes in the secondary thread at the same time as the main thread is executing the calls in the main function.

The first parameter to CmtScheduleThreadPoolFunction indicates the thread pool with which you want to schedule the function. The LabWindows/CVI Utility Library contains a built-in default thread pool. You pass the constant DEFAULT_THREAD_POOL_HANDLE to indicate that you want to use the default thread pool. You cannot customize the behavior of the default thread pool. You can call CmtNewThreadPool to create a customizable thread pool. CmtNewThreadPool returns a thread pool handle, which you pass in the first parameter to CmtScheduleThreadPoolFunction. You must call CmtDiscardThreadPool to free the resources of a thread pool that you create with CmtNewThreadPool.

The last parameter to CmtScheduleThreadPoolFunction returns an identifier that you use to reference the scheduled function in subsequent function calls. The call to CmtWaitForThreadPoolFunctionCompletion causes the main thread to wait until the thread pool function has finished executing before completing. If the main thread exits before the secondary threads finish executing, the secondary threads might not get a chance to properly clean up resources that they allocated. Any libraries used by those secondary threads also might be denied an opportunity to clean up properly.