LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Multithread lock discarding

Hi ! I've done a program that communicates using serial interface. I divided the program in three threads: one for the UI, another for a timer (asynchronous timer) and the last one communicates to serial port. In this last thread I use many 'if statements' on some flags (which can be modified by the other two threads), so I created a thread lock to lock these variables during the execution of the if statement:

CmtGetLock (thread_lock);
if (flag.data_ready)
{
...
}
CmtReleaseLock (thread_lock);

CmtGetLock (thread_lock);
if (flag.wait_data)
{
...
}
CmtReleaseLock (thread_lock);
.
.
.

Everything seems working very well, but when I close the program, it hangs on the command

CmtDiscardLock (thread_lock);

I called this
function after CmtWaitForThreadPoolFunctionCompletion.

The only solution is to close the program from task manager.
Where is the error ?

Thank you !
0 Kudos
Message 1 of 4
(3,256 Views)
If the lock has been acquired by one thread and you are discarding it from another thread, then the discarding thread will wait in the CmtDiscardLock function for the lock to be released by the first thread. The CmtDiscardLock function panel help says the following:

"If a thread currently owns the thread lock, this function waits for the thread to release the lock before uninitializing the lock."

I think one of your threads might have acquired the lock and not released it. Note that each CmtGetLock must be balanced by a corresponding CmtReleaseLock from the same thread.

If you are using many global flags controlled by just one lock there is more chances of bugs that lead to race conditions. I would recommend that you make the flags thread-safe variables (so eac
h flag will have its own lock, and the locking is automatically managed for you).

Best regards,
Mohan
0 Kudos
Message 2 of 4
(3,256 Views)
Ok, I think it's a good idea. But I sholud use the flag in safe mode only to CHANGE the value of the variable, isn't it ? The problem should be if two threads writes in the same moment to the same variable. So what can I do when I only read value in 'if' and 'while' statements ? If I access the variable in safe mode here:

while (!flag.byte_written);

I think that I will never pass this command even if the other thread switched the flag.byte_written to 1.

Am I right ?? (I'm confused....)
0 Kudos
Message 3 of 4
(3,256 Views)
You are right. There is nothing wrong with using flags and locks if you two or more threads will not set the same flag at the same time. It is just that I have seen more bugs when the code uses one lock controlled by many flags. Check your code to make sure that all your threads release the lock each time they get it under all flag settings. It is the last part that is hard - analysing the code to make the lock is released correctly under various combinations of flag values. Using thread safe variables or separate locks for each flag would reduce this complexity. Also, if only one thread is ever going to write to a flag and other threads only read the flag value, and if the flag is a 4-byte integer, then you do not need a lock, as setting 4-byte integer
values is atomic.
0 Kudos
Message 4 of 4
(3,256 Views)