LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing VA data from many threads to one

CVI 2013SP2, Win7.

 

Most of my data acquisition & control applications log data, ASCII character strings to a file, and usually a text box at the same time -- system log stuff.  I use a variable argument function call, which looks like this:  int SysLogEntry(const char *tempFormat, ...).  The function goes through the usual conversion to a complete character string, then writes the string to an open file stream, and to a text box if needed.

 

I have found as my multi-threaded applications get larger, with lots of things going on at the same time, the SysLogEntry function is called from more than one thread in close succession.  This causes, as nearly as I can tell, the function to be re-entered one or more times.  This confuses things a bit -- fortunately I have never seen such a thing kill the application.  But what I see is the same character string sent to the text box and/or file, more than once, or things sent out of order.

 

To solve this, I think I need to use a TSQ, but I don't understand if this will work well, with multiple threads sending data to the queue almost but not quite simultaneously.  I think so.  Perhaps someone out there has done something like this.

 

The second issue I have here is properly passing this data into the TSQ, and using it properly when taken out.  As seen above, the data needed to be passed is a format string and a variable argument list.  is there a way to put, fetch and use this kind of variable data?

 

While writing this I have thought that perhaps there needs to be code within each thread that converts the format string and variables into a character string, which is then written to the TSQ.  That is the first thing that the SysLogEntry function does anyway.  The TSQ callback then reads the character string, does not have to do any work on it, just writes it to the file and the text box.  This kind of change is pretty minor.

 

Some help with either or both issue will be appreciated.

0 Kudos
Message 1 of 4
(4,515 Views)

I have realized something similar to your scenario and went the second path you depicted (i.e. creating the output string inside the thread and passing it to the logging function). The only difference in my solution was to call the logging function with PostDeferredCall, passing the address of the string in callbackData parameter. The log function must then dispose of the memory after handling it. Calling in PostDeferredCall guarantees that the logging function is executed in the main thread, thus relieving the threads from such job (and possible I/O errors and so).

I tested this solution in a low-rate scenario (logging at 3-5 Hz) without problems: can this be a possible solution for your system too?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 4
(4,472 Views)

Thank you Roberto.  I created a small application yesterday to work on this.  First tried messing with TSQ's without much success.  The documentation says one thread writes to a TSQ and one reads from it.  And it means it.  Multiple threads writing to a TSQ just confuses it and strings are dropped.

 

Reworked the app to process the VA info into a character string in each thread, then pass the string pointer via PostDeferredCall to the Callback in the main thread and it seems to work fine.  My app launches 4 threads, and worst case, issues 4 log entries within microseconds of each other, twice a second.  Next is to write two or three strings from within each thread with no gaps, then a half second gap, to see if they stomp on each other.  I suspect they will since I am not managing the char array memory.  This is a worst case scenario that my big apps would probably never do, but hey, let's make this robust.  Figure within each thread string prep function, I can ping-pong two or three different arrays.

 

Thanks again...

0 Kudos
Message 3 of 4
(4,463 Views)

I don't suppose strings overlap between calls to logging function: if you malloc each string in the thread and free it in logging function all should work well.

What it may happen is that you write a message from thread 1, next one from thread 2 and next one from thread 1 again. I see no easy way of avoiding it.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 4
(4,461 Views)