LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

multithreading and arrays

Hi,
 
I'm developping a program. I have to use two different threads. One to monitor continuously the answers from an automat, and another one to handle and display these answers.
I need a char array to link the first thread to the second one.
There is in the utility.h library a 'DefineThreadSafeArrayVar()' function that allows to create thread safe arrays. But I don't know how to set or get some values in or from this array.
It would be great if some function like the GetVarName or SetVarName would exist , but for an array...
 
Thank you for your answers.
 
Benoit Lasceve, Dassault Aviation, France.
0 Kudos
Message 1 of 5
(3,902 Views)

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

0 Kudos
Message 2 of 5
(3,896 Views)

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. 

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

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();
}

Message 4 of 5
(3,868 Views)

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);

 

 

 

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