06-13-2006 04:14 AM
06-13-2006 04:53 AM
Hello Benoit,
I'm not very familiar with the Tread Safe Arrays, but there is an article called "Multithreading in Labwindows/CVI" where it is discussed. Take a look at page 8. You can find the article here: http://zone.ni.com/devzone/conceptd.nsf/2d17d611efb58b22862567a9006ffe76/2df76d8073aa2a8c86256d2c005...
Success,
Wim
06-13-2006 06:23 AM
ok,
Thank you for answering.
I've already read this document, but it is not very accurate about arrays used in multithread programs.
But may-be I will do it another way. I think I can do it with a Global var array and lock it when I read or write in it. That should work like that and it is quite simple.
But if anybody could explain me about the thread safe arrays, that would be great.
thanks,
Benoit.
06-13-2006 09:56 AM
The thread safe variable functions in the Utility Library can be a little difficult to use correctly because they are type-agnostic. So the Utility Library provides macros in utility.h that create type-safe helper functions to create and use thread safe variables. An example of thread safe scalar variables is shown in samples/utility/threading/threadsafevar/incrementvalue.c. Thread safe array variables are similar, except you do not have Get/Set helper functions - you have to use the GetPointer/ReleasePointer functions. Here is a simple example that hopefully helps illustrate how to create and use a thread-safe array variable:
#include <windows.h>
#include <utility.h>
#include <formatio.h>
#include <ansi_c.h>
/* Define a thread safe array variable called Buffer of type char[4] with nesting = 1 */
DefineThreadSafeArrayVar(char, Buffer, 4, 1);
int CVICALLBACK ThreadFunction(void * threadData)
{
int i, writer = threadData != NULL;
for (i = 0; i < 100; ++i)
{
/* Lock Buffer and get pointer to its first element */
char * buffer = GetPointerToBuffer();
if (writer)
{
int j;
/* Write some random data in Buffer */
for (j = 0; j < 4; ++j)
buffer[j] = 'a' + (rand() % 26);
}
else
{
/* Read and print the values in Buffer */
FmtOut("%s<%4c\n", buffer);
}
/* Unlock Buffer */
ReleasePointerToBuffer();
Sleep(100);
}
return 0;
}
void main(void)
{
int pool = 0;
/* Initialize Buffer */
InitializeBuffer();
/* Spawn two worker threads */
CmtNewThreadPool(2, &pool);
CmtScheduleThreadPoolFunction(pool, ThreadFunction, (void *) 1 /* writer */, NULL);
CmtScheduleThreadPoolFunction(pool, ThreadFunction, NULL /* reader */, NULL);
CmtDiscardThreadPool(pool);
/* Uninitialize Buffer */
UninitializeBuffer();
getchar();
}
06-13-2006 12:47 PM
Maybe we're making this way more complicated than it needs to be ....
If all of the threads involved are within the same process, a Win32 CriticalSection is by far the simplest mechanism available to coordinate (i.e. serialize) access to a common data structure like an array. They're very easy to use as well. See Beveridge & Weiner ISBN 0-201-44234-5
CRITICAL_SECTION gCriticalSection;
double dArray;
...
InitilaizeCriticalSection(&gCriticalSection);
...
void ArrayWrite(iIndex, dValue) {
EnterCriticalSection(&gCriticalSection);
dArray[iIndex] = dValue;
LeaveCriticalSection(&gCriticalSection);
return;
}
double ArrayRead(iIndex) {
double dValue;
EnterCriticalSection(&gCriticalSection);
dValue = dArray[iIndex];
LeaveCriticalSection(&gCriticalSection);
return dValue;
}
...
DeleteCriticalSection(&gCriticalSection);