I am hunting a possible deadlock in my program and im suspecting the following.
What happen if 2 threads at the same time calls EnterCriticalSection and thread #1 calls DeleteCriticalSection right after entering, what happen to thread #2 which is still in EnterCriticalSection call?
Thanks.
Two threads cannot enter the critical section at the same time. That would defeat the purpose of a critical section. Either Thread #1 enters the critical section first, or Thread #2 enters the critical section first. You have two possible interleavings at play here.
Let’s say that the interleaving is this:
Thread 1 Thread 2 -------- -------- | | | | EnterCS() | Lock Taken | | | | EnterCS() | Blocked | | | | DeleteCS() | | | | ??? | ...In this case, the state of thread #2 is undefined according to MSDN:
So if you’re unlucky enough for your two threads to encounter the above interleaving, then the operating system gives you no guarantee that your program will continue to work as expected. That can include deadlocking Thread #2, for example.
But if the interleaving is this:
Thread 1 Thread 2 -------- -------- | | | | | EnterCS() | Lock Taken | | EnterCS() | Blocked | | | | | | ExitCS() | Lock Released | | Unblocked | LockTaken | | | DeleteCS() | | | | | ... ...Then obviously, since Thread #1 is blocked, it can’t delete the critical section, until Thread #2 leaves the critical section. Then assuming no other threads enter the critical section, Thread #1 will be able to delete it with no problems.
The scenario that you propose is essentially a race condition. Depending on the timing of the threads, it may work just fine or cause unpredictable problems. In this case, you have to restructure your code such that the destruction of the critical section happens after all interested threads have released the critical section.
In this two-thread scenario, one way to fix it is to have Thread #1 leave the critical section and wait for all the other threads to finish first before deleting the critical section. Something like this, for example:
Now, the two possible interleavings look like this:
Thread #2 acquires lock first: . Thread #1 acquires lock first: . Thread 1 Thread 2 . Thread 1 Thread 2 -------- -------- . -------- -------- | | . | | | EnterCS() . EnterCS() | | Lock Taken . Lock Taken | | | . | | EnterCS() | . // Do stuff EnterCS() Blocked // Do stuff . | Blocked | | . | | | | . ExitCS() | | ExitCS() . Lock Released | | Lock Released . | | | | . | Unblocked Unblocked | . | Lock Taken Lock Taken | . | | | | . | // Do stuff // Do stuff | . | | | | . | ExitCs() ExitCS() | . | Lock Released Lock Released | . | | | | . | | | | . | | WaitForThread2() --+ . WaitForThread2() --+ | . | DeleteCS() . DeleteCS() | . | | . | done . doneThe exact implementation for
WaitForThread2()is going to depend on the nature of your program, but would certainly involveWaitForSingleObject()or any one of its relatives.