Discussion:
CCriticalSection
(too old to reply)
Wesley Henwood
2004-07-25 14:52:38 UTC
Permalink
In the following code, program execution does not deadlock at line 3,
as I expect it should, but rather continues and increases the lock
count of critical section c. How can I make the program wait at line
3?

1. CCriticalSection c;
2. c.Lock();
3. c.Lock();
Doug Harrison [MVP]
2004-07-25 16:22:19 UTC
Permalink
Post by Wesley Henwood
In the following code, program execution does not deadlock at line 3,
as I expect it should, but rather continues and increases the lock
count of critical section c. How can I make the program wait at line
3?
1. CCriticalSection c;
2. c.Lock();
3. c.Lock();
In Windows, mutexes[*] are recursive, which means the thread that has
acquired the mutex can reacquire it. I guess I don't get the question,
because if you were to block at (3), how would you ever unblock? After all,
only the thread that acquired the mutex can release it.

[*] When it doesn't matter, I refer to CRITICAL_SECTION and the kernel-level
mutex object as "mutexes", which is a lot less awkward to type than
CRITICAL_SECTION or CCriticalSection, which aren't very good names anyway.
The code sequence between the lock/unlock calls has traditionally been
called the "critical section", not the synchronization object itself.
--
Doug Harrison
Microsoft MVP - Visual C++
Jeff F
2004-07-26 13:19:55 UTC
Permalink
Post by Doug Harrison [MVP]
Post by Wesley Henwood
In the following code, program execution does not deadlock at line 3,
as I expect it should, but rather continues and increases the lock
count of critical section c. How can I make the program wait at line
3?
1. CCriticalSection c;
2. c.Lock();
3. c.Lock();
In Windows, mutexes[*] are recursive, which means the thread that has
acquired the mutex can reacquire it. I guess I don't get the question,
because if you were to block at (3), how would you ever unblock? After all,
only the thread that acquired the mutex can release it.
[*] When it doesn't matter, I refer to CRITICAL_SECTION and the kernel-level
mutex object as "mutexes", which is a lot less awkward to type than
CRITICAL_SECTION or CCriticalSection, which aren't very good names anyway.
The code sequence between the lock/unlock calls has traditionally been
called the "critical section", not the synchronization object itself.
I was under the impression that there are semantic differences between
CCriticalSection and CMutex. One property is that CMutex allows recursive
locks from the same thread, whereas CCriticalSection blocks(deadlocks) when
recursively locked from the same thread. Am I mistaken?

Jeff F
Doug Harrison [MVP]
2004-07-26 15:04:35 UTC
Permalink
Post by Jeff F
I was under the impression that there are semantic differences between
CCriticalSection and CMutex. One property is that CMutex allows recursive
locks from the same thread, whereas CCriticalSection blocks(deadlocks) when
recursively locked from the same thread. Am I mistaken?
They're both recursive. The differences between the Windows mutex object and
CRITICAL_SECTION don't apply to your problem, but for the record, they are:

1. The Mutex is a kernel object, represented by a HANDLE, while
CRITICAL_SECTION is not.

2. The other differences mainly follow from (1). For instance, you can use a
Mutex with WaitForSingleObject and friends, but this is not possible for
CRITICAL_SECTION. (NB: One of several design flaws in this part of MFC allow
you to use CCriticalSection with the MFC lock classes, but debug builds will
assert if you try this.) Mutexes can be named and used across processes,
while neither is possible for CRITICAL_SECTION. Locking a mutex requires
dropping into kernel mode, while locking a currently unacquired
CRITICAL_SECTION does not. And so on. For these reasons, a CRITICAL_SECTION
can be thought of as a lightweight mutex. (I wish they had named it
accordingly. :)
--
Doug Harrison
Microsoft MVP - Visual C++
Loading...