LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Thread Safe Queue callback won't fire

I am trying to use a thread safe queue to transfer aqcuired data and status strings from one thread of my program to a separate thread of my program.

No matter what I seem to do, the queue callback function I define and install never gets triggered. I can stuff data into the queue until it overflows but the callback is never triggered even when I tell it the threshold is one item.

Anyone have any suggestions or insight here?

I am using pretty much the same method as is used in the sample file BuffNoDataLoss.c
Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 1 of 6
(4,022 Views)
I found that by calling ProcessSystemEvents() right after stuffing data into my queue will SOMETIMES get the callback to fire. But not everytime I expect it to, this is quite frustrating.

This isn't documented very well anywhere, not in the function panel for CmtInstallTSQCallback() or in the sample program.

Message Edited by MJF on 03-18-2005 04:56 PM

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
Message 2 of 6
(4,017 Views)
I'm talking to myself but I think this might help somebody in the future.

I finally got it to do most of what I want it to do but still need to do some fine tuning. I can get the callback to fire properly now by inserting the calls to ProcessSystemEvents() as noted above. The other thing that was tripping me up was how CmtReadTSQData() works. It will only return when it gets the exact number of items you tell it to. The problem I was having is that I don't know how many items that will be each time I put something in the queue.

What I did to fix this is simple. In my call to CmtInstallTSQCallback(), I set the threshold at 1 item. When I write a string to the queue, the callback fires. Now it appeared that the callback hung up at that point until the queue was full. The problem was that CmtReadTSQData() was blocking until it got as many items as I had asked for (the full queue size).

Fortunately, I could force the queue to retrieve only what was actually in the queue by getting the number of items using CmtGetTSQAttribute() and passing that value to CmtReadTSQData()

Problem solved except for the fact that sometimes there is more than one string in the queue. That's an easy problem, I can simply put a termination character at the end of each and string and break the data up accordingly.

So I'll quit before I ramble on into the sunset. Time to go have my weekend.
Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 3 of 6
(4,011 Views)
Martin,

You just THOUGHT you were talking to yourself... my 2 cents.

I do a lot of CVI applications using multiple threads. Most of my work has to do with acquiring data at one rate, EU converting it and bounds testing it, and displaying it at another rate, saving it to file at a third rate, etc, etc.

To date, I've avoided having to deal with thread safe variables and queues by doing some very simple things. First, you don't need thread safe variables (single cells or arrays), if you only write to them from one thread. You can read from them in all your other threads.

The need for queue in your application implies that something is happening faster in one thread than another, and the second thread must respond to everything that happens in the first (ie, multiple strings in the queue) in sequence. Not that I'm scared to jump into thread safe variables/queues, but considering the difficulty you encountered, I would probably approach it in a similar fashion to the above. The thing to do is create a delay loop in the second thread that is looking for a flag from the first. When that flag is asserted, it snatches the available string and processes it.

while (runThisThread)
0 Kudos
Message 4 of 6
(3,983 Views)
Martin, (dang this thing -- I hit return and it sent the message before I was done)

You just THOUGHT you were talking to yourself... my 2 cents.

I do a lot of CVI applications using multiple threads. Most of my work has to do with acquiring data at one rate, EU converting it and bounds testing it, and displaying it at another rate, saving it to file at a third rate, etc, etc.

To date, I've avoided having to deal with thread safe variables and queues by doing some very simple things. First, you don't need thread safe variables (single cells or arrays), if you only write to them from one thread. You can read from them in all your other threads.

The need for queue in your application implies that something is happening faster in one thread than another, and the second thread must respond to everything that happens in the first (ie, multiple strings in the queue) in sequence. Not that I'm scared to jump into thread safe variables/queues, but considering the difficulty you encountered, I would probably approach it in a similar fashion to the above. The thing to do is create a delay loop in the second thread that is looking for a flag from the first. When that flag is asserted, it snatches the available string and processes it.

while (runTheSecondThread)
{
Delay (x.y);
if (flagFromFirstThread) processTheString();
doOtherStuff;
}

... just my way of keeping things simpleminded...

There are other ways to do this, that might be more reliable than the problem you encountered, like posting a user defined event to a callback you install at runtime.

Regards... Gary
0 Kudos
Message 5 of 6
(3,982 Views)
Well, I have it working the way I want it to so no worries.

I have to use thread safe variables in a few places because I am using them as semaphores to synchronize what is going on in the threads. That means that two threads can write to the flag so a thread safe variable is essential.

The thread safe queue is also essential. I really need to maintain the order of data retrieved by the test sequence thread so it can be properly reported in the data log file which is written in another thread to avoid blocking the sequence thread.

This is not a high-performance application that I am doing but it does need to execute in the shortest time possible because it will be used in a manufacturing environment and as the saying goes, time is money.
Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 6 of 6
(3,979 Views)