LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

thread pool ownership

Hi,

 

when shutting down a multithreaded application, the main thread schedules functions that will terminate the secondary threads, using PostDeferredCallToThread ( callback_function, callback_data, thread_id ) in a loop over all seconadry threads.

 

This works fine, and I can close the application as intended. 

 

However, if I add another line to the loop, as recommended by the NI sample programs, CmtWaitForThreadPoolFunctionCompletion ( pool_handle, thread_function_id, OPT_TP_PROCESS_EVENTS_WHILE_WAITING ),

 

I receive an error message:

 

The function ID you passed is owned by the thread pool. This operation can only be performed on a function ID that you own.

 

This loop is initiated by the main thread, so how can the thread pool own a function ID?

 

I am using the pool handle that I obtained from the CmtNewThreadPool and not the default thread pool handle.

 

Thanks (and no more posts today)

 

Wolfgang

0 Kudos
Message 1 of 5
(3,871 Views)

Hi Wolfgang.

 

Keep in mind that callback_function you specify in the CmtWaitForThreadPoolFunctionCompletion() call will not execute until the thread becomes idle, so thread_function_id will not be valid.

 

Here is a simple approach that works for me:

 

int Shutdown;    // global variable

int myThreadPool;

 

int main (int argc, char *argv[])
{

  Shutdown = 0;

  CmtNewThreadPool(nThreads, &myThreadPool);

  ...

 

  // Signal threads - application is closing

  Shutdown = 1; 

  CmtDiscardThreadPool(myThreadPool);  // Blocks until all threads in thread pool are idle

 

  return 0;

}

 

Each thread function (including those running in the default thread pool) includes lines similar to:

  while(!Shutdown && someOtherCondition)

    ProcessSystemEvents();

  return 0;

 

Colin.

 

Message Edited by cdk52 on 05-11-2009 10:07 AM
0 Kudos
Message 2 of 5
(3,855 Views)

Hi Colin,

 

sounds reasonable, but still this answer is confusing me because...

 

Recently, I have obtained a nice sample code from Roberto (here http://forums.ni.com/ni/board/message?board.id=180&message.id=41004#M41004)

 

which does exactly (?!) the same thing:

 

  PostDeferredCallToThread (QuitUICallback, 0, threadID);
  CmtWaitForThreadPoolFunctionCompletion (poolHandle, fnID, OPT_TP_PROCESS_EVENTS_WHILE_WAITING);

and it worked just fine...

 

Wolfgang

 

0 Kudos
Message 3 of 5
(3,837 Views)

Hello Wolfgang.

 

My apologies. When you wrote "...the main thread schedules functions..." I assumed that you were calling CmtScheduleThreadPoolFunction() or CmtScheduleThreadPoolFunctionAdv() - I ignored "...using PostDeferredCallToThread()...".

 

I looked at the modified MultiPanel sample provided by Roberto. If your code is similar in structure, I can see no reason why it should not work as you expect.

 

Does your code include any calls to CmtReleaseThreadPoolFunctionID()? I imagine that if you call CmtWaitForThreadPoolFunctionCompletion() after the function ID has been released, you will generate an error.

 

Good luck.

 

Colin.

 

0 Kudos
Message 4 of 5
(3,822 Views)

Hi Colin,

 

Thanks for suggesting to check for CmtReleaseThreadPoolFunctionID. Indeed I had such a call, but even if commenting it out the error remains the same. By the way, when calling CmtReleaseThreadPoolFunctionID instead of CmtWaitForThreadPoolFunctionCompletion, I receive the same error...?? This seems to suggest that something with my pool handle is wrong, but I make use of it only once, when starting the secondary threads from the primay threads using

 

CmtScheduleThreadPoolFunctionAdv ( pool_handle, thread_function, thread_function_data, csi_process_class, callback_function,

( EVENT_TP_THREAD_FUNCTION_BEGIN || EVENT_TP_THREAD_FUNCTION_END ), 0, RUN_IN_SCHEDULED_THREAD, NULL )

 

I can't see anything wrong here... 

 

Wolfgang

0 Kudos
Message 5 of 5
(3,815 Views)