Avoiding Deadlocks
When two threads are waiting for thread-locking objects that are held by each other, execution cannot continue. This condition is referred to as a deadlock. If the user interface thread is deadlocked, it cannot respond to input from the user. The user must exit the application abnormally. The following example illustrates how a deadlock can occur.

Similar to errors that occur from not protecting data, deadlock errors are often intermittent because of differences in the timing of thread switches in different executions of a program. For example, if the switch to Thread 2 does not occur until after Thread 1 holds both lock A and lock B, Thread 1 is able to complete its work and release the locks for Thread B to acquire later. A deadlock like the one described in the previous section can occur only when your threads acquire more than one lock at the same time. You can employ a simple rule to avoid this kind of deadlock. When acquiring more than one thread-locking object, every thread in your program must always acquire the thread-locking objects in the same order. The following LabWindows/CVI Utility Library functions acquire thread-locking objects and return without releasing them.
- CmtGetLock
- CmtGetTSQReadPtr
- CmtGetTSQWritePtr
- CmtGetTSVPtr
Note Typically, you do not call CmtGetTSVPtr directly. It is called by the GetPointerTo accessor function that the DefineThreadSafeScalarVar macro creates. Therefore, you must treat every GetPointerTo function that you call as a thread-locking object acquire function with respect to deadlock protection.
Some Windows SDK functions, including the following, can acquire thread-locking objects without releasing them before returning.
![]() |
Note This is not a comprehensive list. Refer to www.msdn.com for more information about Windows SDK functions. |
- EnterCriticalSection
- CreateMutex
- CreateSemaphore
- SignalObjectAndWait
- WaitForSingleObject
- MsgWaitForMultipleObjectsEx