This is simple: use some logic and answer your own question. "Not synchronized for critical sections"
is not a logically consistent statement. As "critical section" is actually the synchronization primitive itself, in real code it may mean a) you are using critical section correctly and the threads are actually synchronized; b) you are not using critical section; or don't use it properly, which may lead to any unpredictable behavior, including
deadlock. Actually the term "critical section" may mean two different related things: 1) critical section object implementing mutual exclusion; 2) some section of code interlocked using this primitive.
You just need to understand how
mutual exclusion works:
http://en.wikipedia.org/wiki/Mutual_exclusion[
^],
http://en.wikipedia.org/wiki/Deadlock[
^].
Note that mutual exclusion is not the method of eliminating of a dead lock, not at all. This is a method of keeping integrity of some code fragment. Imagine you have two integers
A
and
B
, accessible by two or more threads. Imaging that you have an invariant:
A
+
B
==
C
, where
C
is some constant. Then you need to provide some
atomic operation to keep this invariant in a multhreaded situation. (See also:
http://en.wikipedia.org/wiki/Atomicity_%28programming%29[
^]). How can you do it? For example
int delta = A += delta;
B -= delta;
Imagine what happens if one thread increments one of these values, and then some other thread does the same, before first thread is done, and uses resulting
A
and
B
? What happens to your invariance? To prevent that, it's enough to allow only one thread at a time entering this fragment of code. This is done via mutexes or critical section objects (light version of mutex, actually). Note that it is absolutely impossible to achieve this effect but using any threading APIs, just with "ifs" and other programming control structures. A mutex put threads in a queue and in the special wait state where a thread is switched out and is not using any CPU time, until its waken up (by timeout, "green light" from a mutex, other events, interrupt system is involved).
And this is the well-known, classical way of making a deadline:
LPCRITICAL_SECTION sc1 = LPCRITICAL_SECTION cs2 =
EnterCriticalSection(sc1);
EnterCriticalSection(sc2);
LeaveCriticalSection(sc2);
LeaveCriticalSection(sc1);
EnterCriticalSection(sc1);
EnterCriticalSection(sc2);
LeaveCriticalSection(sc1);
LeaveCriticalSection(sc2);
I'll leave for you home exercise to figure out why this is a deadlock. This is a very useful exercise; it will help you to understand how it all works.
[EDIT]
It's important to understand that typical threading bugs cannot be detected using the debugger and even testing because the behavior and order of operations start to depend on timing. The code should be analyzed and corrected theoretically.
[END EDIT]
Please see:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682608%28v=vs.85%29.aspx[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684169%28v=vs.85%29.aspx[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686360%28v=vs.85%29.aspx[
^].
See also my past answer:
Write thread safe code[
^].
—SA