Coordinating threads Part I
The most complex task when developing multithreaded
application is to coordinate threads and make them work together.
When writing the thread executable code, you must consider the
behavior of other threads that may be executing simultaneously,
including the main VCL thread. Thread executable code can be
interrupted at any time. Each thread code runs simultaneously.
In particular, you should avoid two threads trying to use the
same global object or variable at the same time.
Note that local variables are always thread-safe, because each
thread has its own stack memory.
Avoiding simultaneous access
To avoid clashing with other threads when accessing global
objects or variables, you may need to block the execution of
other threads until your thread code has finished an operation.
Be careful not to block other execution threads unnecessarily.
Too many locks can cause performance to degrade seriously and
negate most of the advantages of using multiple threads. Improper
usage of locking objects and / or critical sections can cause
deadlock.
Locking objects
Some objects have built-in locking that prevents the execution
of other threads from using that object instance.
For example, canvas objects (TCanvas and descendants) have a Lock
method that prevents other threads from accessing the canvas
until the Unlock method is called.
The VCL also includes a thread-safe list object, TThreadList.
Calling TThreadList.LockList returns the list object while also
blocking other execution threads from using the list until the
UnlockList method is called. Calls to TCanvas.Lock or
TThreadList.LockList can be safely nested. The lock is not
released until the last locking call is matched with a
corresponding unlock call in the same thread.
Note: Lock/Unlock methods itself use critical sections or other
synchronization mechanism but there is no any "compiler
magic".
Using critical sections
If objects do not provide built-in locking, you can use a
critical section. Critical sections work like gates that allow
only a single thread to enter at a time. To use a critical
section, create a global instance of TCriticalSection.
TCriticalSection has two methods, Acquire(which blocks other
threads from executing the section) and Release(which removes the
block).
Each critical section is associated with the global memory you
want to protect. Every thread that accesses that global memory
should first use the Acquire method to ensure that no other
thread is using it. When finished, threads call the Release
method so that other threads can access the global memory by
calling Acquire.
Warning:
Critical sections only work if every thread uses them to access
the associated global memory. Threads that ignore the critical
section and access the global memory without calling Acquire can
introduce problems of simultaneous access.
For example, consider an application that has a global critical
section variable, LockXY, that blocks access to global variables
The copyright of the article
Coordinating threads Part I in
Delphi Programming is owned by Lyapin Ilya. Permission to republish
Coordinating threads Part I in print or online must be granted by the author in writing.
Go To Page:
1
2
Articles in this Topic
Discussions in this Topic