Multi-threaded programs can share the same data and by default the switch from
processing one thread to another can take place at any time. Sometimes it
is necessary to protect shared data by making sure that a calculation in
one thread is not interrupted by processing (that uses or changes the
shared data) in another thread. One simple example of this is where
two threads READ from (or WRITE to) the same Fortran unit.
Another is where one thread must update a data structure that is used by
another thread. The simplest way to achieve this is to use the LOCK statement:
<some sensitive statements>
The system prevents a swap to another thread whilst the statements within
a LOCK block are being executed. Once a block has been entered, other
threads are forced to wait until the block has been completed.
In some cases it is useful to apply a more selective locking mechanism. A lock
can be applied to any .NET object (typically stored in a FTN95 module).
The object must be created (using NEW@) before a LOCK statement is
! Some sensitive statements...
This form of the LOCK statement only operates in relation to other locked
blocks (in a different thread) that refer to the same object.
Here are some rules for locking:
1. One lock has no effect upon other locks in the same thread.
2. Using the same lock a second time (i.e. nesting) has no
3. If a locked block is exited prematurely (because an exception is
raised) the corresponding lock is removed.
4. You must not enter or exit a locked block via a GOTO statement.
Programs with multiple threads can contain bugs that arise from the interaction
of the various threads. In particular, if different threads use and change
the same data, a program can produce results that vary from one run to another
(because the results depend upon the order in which the threads have
been executed). A temporary LOCK wrapped around a significant block
of code can be used to identify a threading bug of this kind. The
temporary lock forces the code to run serially thus preventing the
possibility of a threading bug occurring in this part of the code.
It is also possible to synchronise threads at a lower
level by directly calling methods in the System.Threading.Monitor
class. These methods can be used to develop a more elaborate
system of thread interaction. For example, you could perform a
new task whilst waiting for data for the current task to