EMThread |
1. Overview
2. General issues
2.1. Compiling multithreaded applications
2.2. Memory management
2.2.1. Object exchange
2.2.2. Garbage collection
2.3. Synchronization
2.3.1. Attribute accesses and routine
calls
2.3.2. Once-routines
2.3.3. Input/output
2.4. Exceptions handling
3. Library description
3.1. Class EMT_THREAD
3.1.1. make
3.1.2. start
3.1.3. run
3.1.4. sleep
3.1.5. suspend
3.1.6. exit
3.2. Class EMT_CRITICAL_SECTION
3.2.1. make
3.2.2. lock
3.2.3. unlock
3.2.4. dispose
The library represents low-level implementation of multithreading facilities. It does not keep track about all possible situations which may cause application to crash. The library relies on the programmer who uses it that all these situations are under his control. It should be used with extreme care.
In order to use the library, special run-time features should be linked into the application module. This is controlled by the Eiffel System Description file. In the section "option" you should specify
multithreading on
It will provide all necessary run-time routines.
This implementation of multithreading relies on the fact that all threads share the same memory space. It means that all objects are stored in the same address space and may be accessed directly from different threads. However, there are many restrictions on object interchange.
It is not safe in the thread to access object from another thread. There are the following scenarious which may ensure that objects are exchanged safely:
STORABLE
, FILE
, PERSISTENT_ARRAY
).Objects of type STRING
or ARRAY
or one of it descendants should never be references from the thread it does not belong to.
Standard features of class GENERAL
which perform object
copying (such as copy
, clone
, etc.)
will report an error if the copying involves objects belonging to another thread.
Garbage collection is performed on the per-thread basis. It means that every object belongs to the one thread. If there are no references in the thread to its object, the object is considered as being unreachable and may be disposed.
Thus, keeping references in one thread to objects in another thread is not safe, because such object can be easily removed by the garbage collector causing hanging pointers to occur. If the application requires such a references, it should be done in a way that ensures that the thread objects will not be removed by the garbage collector if they are referenced in another thread.
It should be noted that after the thread finishes, all its objects are disposed.
When accessing in one thread object from another thread, special care should be taken to avoid incorrect processing. For the access is performed from another thread, the object may be changing by its native thread that may lead to inconsistent results. For example,
a := x.b
- where x
belongs to another thread and a
and b
are of multi-byte expanded type may result in misformed a
, because thread x
sets value of b
at the same time as the given assignment is performed.
The same problem occurs when a feature of the object belonging to another thread is called. Then two threads may concurrently change the same object.
In order to avoid this problem, synchronization should be used.
Once-routines behave as ordinary features and therefore special care should be taken to ensure that only one thread calculates the result of once-function. It is a good practice to initialize all once-functions before starting any threads.
The run-time does not synchronize any input/output from different threads. This should be programmed by the developer. However, it ensures that input/output would not destroy any objects. Objects belonging to other thread cannot be used for input or output.
Exceptions raised in one thread are never propagated into another thread. If exception is not caught by any feature of the thread using "rescue" clause, the thread stops.
Class EMT_THREAD
implements basic features of multithreading
environment. In order to create threads, some class in the system should inherit this
class and implement feature run
. New thread is created every
time when new instance of the class is created.
make
This feature should be declared as "creation" in the class which inherits
class EMT_THREAD
. This will cause the run-time to create new
thread when corresponding object is created.
start
The thread created by the routine make
is not running. It
remains in suspended mode until feature start
is called. The
period between object creation and invoking start
may be used
to initialize object attributes.
run
Feature run
is declared in class EMT_THREAD
as a deferred one. It is invoked automatically when the thread is started. Thread stops
when feature run
is exited.
sleep (msec: INTEGER)
The feature causes thread to suspend for the given amount of milliseconds and then to resume.
suspend
The feature causes thread to suspend for unlimited period of time. The thread is
resumed when feature start
is called.
exit (code: INTEGER)
The feature causes thread to exit with the given exit code. The thread which has exited cannot be resumed and is a subject for garbage collection.
Class EMT_CRITICAL_SECTION
represents basic primitives for
synchronization.
make
Creation procedure of the class.
lock
Only one thread is allowed to lock the same EMT_CRITICAL_SECTION
object at a time. All other threads which try to lock the object suspend until the object
become unlock. Multiple locks on the same objects performed by the same thread will not
block it.
unlock
The feature unlocks locked EMT_CRITICAL_SECTION
object
allowing other threads to lock it.
dispose
Disposes EMT_CRITICAL_SECTION
object disabling its future
use. This feature is usually called automatically by garbage collector. However, if the
program does not require the object, it may call it to free resources allocated by
operating system.