Once your application is multi-threaded, concurrent data access should be
protected. We already wrote about how debugging multi-thread
applications may be hard.
Otherwise, a "race
condition" issue may appear: for instance, if two threads modify a variable
at the same time (e.g. decrease a counter), values may become incoherent and
unsafe to use. Another symptom of broken logic is the "deadlock", by which the whole
application appears to be blocked and unresponsive, when two threads have a
wrong use of the lock, so are blocking each-others.
On a server system, which is expected to run 24/7 with no maintenance, such
issues are to be avoided.
In Delphi, protection of a resource (which may be an object, or any
variable) is usually done via Critical
A critical section is an object used to make sure, that some part of
the code is executed only by one thread at a time. A critical section
needs to be created/initialized before it can be used and be released when it
is not needed anymore. Then, some code is protected using Enter/Leave
methods, which would lock its execution: in practice, only a single
thread would own the critical section, so only a single thread would
be able to execute this code section, and other threads would wait until the
lock is released. For best performance, the protected sections should be as
small as possible - otherwise the benefit of using threads may be voided, since
any other thread would wait for the thread owning the critical section
to release the lock.
We will now see that Delphi's
TCriticalSection may have
potential issues, and what our framework proposes to ease critical
section use in your applications.