07-11-2022 04:04 PM
Hello,
I have built a DLL in CVI which will contain functions called by TestStand. The main function writes some data to a TCP server. It then waits in a loop for the server to send data back. While in the loop it calls ProcessTCPEvents(), so that the TCP callback function can be processed when any data is present.
My issue is that my TCP callback function and this main function will both access a global variable (boolean flag) during execution. Should I use a lock (CmtGetLock) before accessing this variable in both the main function and TCP callback? My understanding is that the TCP callback function is operating on a separate thread. Or is it on the same thread as the main function?
Here is some pseudo-code for my main function:
ClientTCPWrite("write some data to TCP server")
while(timeout == false)
{
ProcessTCPEvents(); // CVI function
ProcessReturnedMessage();
if(globalFlag == true)
break;
Delay(0.1)
}
In my callback function I also access that global flag, but is my callback function only firing when ProcessTCPEvents() is called? In that case, I think it's all on the same thread and not happening concurrently, in which case I would not need to worry whether the global flag is thread safe. On the other hand, if the TCP callback function can fire concurrently, then I would need to use a Lock or some other protective measure.
Thanks
Solved! Go to Solution.
07-12-2022 03:41 AM
The documentation is not entirely clear on the subject, but it does appear that those callbacks are in a separate thread. You can always put a breakpoint in there and check if the ID of the thread is the same as the main thread.
Anyway, when dealing with multithreaded callbacks I usually prefer to call PostDeferredCall() from the threaded callback, in order to 'come back' to the main thread.
On the other hand if your notification variable is an int, its value change is atomic, so no risk of getting incongruent values (but for struct/arrays/strings you indeed need a lock).
07-12-2022 08:08 AM
Thanks for the reply. Can you elaborate on the use of PostDeferredCall()? My understanding is that I would call this from within my TCP callback. But since I'm already in my callback function, I'm not sure what to use for the "deferred function" parameter in PostDeferredCall().
I also had another thought, which is that I am running a loop in the main thread and polling several global variables (a string buffer, a data buffer and a boolean flag), to know when to exit the loop. But since I am looping until certain conditions are satisfied (or a timeout occurs), I shouldn't have to worry about the TCP callback thread concurrently accessing them, since I will loop until they have the expected data in them. If it was a "one time" access, I would think the lock would be more critical. But in this case, it may not be required.
Thoughts?