0

I have a problem with multithreaded program. Let's say I have series of few integer arrays (usually 2 or 3), each processed by a separate thread. I managed to make my computations, but now I would like to return processed array, created inside my thread.

After I start my threads, I start the following loop, which every 0.05 seconds checks for thread completion. This seems to work fine.

int partsPassed = 0;

int* partsCopied;
partsCopied = (int*) malloc (numThreads * sizeof(int));

int currentCopyStatus = 0;

for (n = 0; n < numThreads; n++) {
    partsCopied[n] = 0;
}

// Loop until we copy all parts of array
while (partsPassed != numThreads) {

    // Loop through all parts of original array
    for (n = 0; n < numThreads; n++) {

        if (partsCopied[n] != 1) {

            // Check for finish of computation
            CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_EXECUTION_STATUS, &currentCopyStatus);
            if (currentCopyStatus == kCmtThreadFunctionComplete) {      // If yes, get the array and copy to original array
                CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_RETURN_VALUE, imageThreadPart[n]);
                copyStaticThreadResults(imageRecPart[n]->nrRowStart, imageRecPart[n]->nrRowEnd, imageThreadPart[n]);
                partsCopied[n] = 1; // Copy flag display
                partsPassed++;      // Count all fragments
            }
        }
    }

    Delay(0.05);

}

The problem is that according to the documentation, I cannot get anything more than a mere int out of thread. This results in failure when I try to use the following function - I try to get int** (2D array stored at imageThreadPart[n]) and the function forces me to pass int*.

CmtGetThreadPoolFunctionAttribute(*threadPoolHandle, threadFunctionID[n], ATTR_TP_FUNCTION_RETURN_VALUE, imageThreadPart[n]);

1. Is it possible to use this function to obtain this array?

2. It might be a long shot, but is it possible to copy that array using callback of the following function and pass value returned by thread directly to this callback somehow?

CmtScheduleThreadPoolFunctionAdv (DEFAULT_THREAD_POOL_HANDLE, 
                                   myThreadFunction, // thread function
                                   imageRecPart[n], // my data
                                   THREAD_PRIORITY_TIME_CRITICAL, 
                                   copyThreadResults, // my callback
                                   EVENT_TP_THREAD_FUNCTION_END,
                                   NULL,  // data for callback - but how to pass it from thread here?!
                                   CmtGetCurrentThreadID(),
                                   &threadFunctionID[n]);
irchris102
  • 108
  • 10
  • 1
    Note that a thread cannot "return" something, as it has not been "called" (both with respect to the application, not the threading-library). Do not poll when using threading! Use a queue in your main thread which collects the data of all completed threads. Alternatively a counting semaphore will work, if the data has been owned by the main thread. – too honest for this site Aug 27 '15 at 14:34
  • @Olaf Thank you for your response. I was under impression that when I pass function and structure handle, then the library would let me get results by copying return value or any other way. I should read more about it and try something easier as a sample before I proceed. There is [tutorial](http://www.ni.com/white-paper/3663/en/) and some [examples](http://www.ni.com/example/29662/en/), but they tend to simply modify single control or simple, independent values. Are there any other reference materials? I would really appreciate it. – irchris102 Aug 28 '15 at 06:55
  • "I was under impression ..." Just a simple thought-experiment: If you call the function to start the thread: does it return while tht started thread is still running? - Yes. So how, when - and **where** - do you get the "result" into the thread which started the other tread? Welcom to the wondrful world of asynchronous (and parallel) programming. Please fasten seat belts, there are tar pits all around waiting for the unaware;-) (OTOH if done it right, it is really fascinating). – too honest for this site Aug 28 '15 at 13:00

2 Answers2

1

All your threads share the same memory space, so you can copy the array to a known location in shared memory (perhaps to a location passed to the thread procedure, perhaps to a global variable, perhaps to a buffer the thread allocated itself and is passing a pointer to). Note that, in order to make sure your updates to the data reach the other CPU cores before the notification that it’s been written, you want to use something like an atomic state variable with memory_order_release semantics, or a spinlock.

Davislor
  • 14,674
  • 2
  • 34
  • 49
0

I've been using the DefineThreadSafeScalarVar and DefineThreadSafeArrayVar macros to make multithreaded variable handling easier. It might be worth doing something like

DefineThreadSafeArrayVar(int, partsCopied, MAX_NUM_THREADS, 0);

to define your array (where MAX_NUM_THREADS is just the maximum number of threads your program allows - this has to be set at compile-time)

and then the GetPointerTopartsCopied() and ReleasePointerTopartsCopied() functions to handle your variable access.

rak0ribz
  • 1
  • 1