:
:
:
Documentation
Micro Threads
1. Introduction
Micro-threads are light-weight threads that run in a single system
thread. Micro-threads are cooperatively scheduled by the user, unlike
system threads which are pre-emptively scheduled by the operating
system.
Micro-threads are also called user threads or cooperative routines.
Windows Fibers is an example of a micro-thread implementation.
A switcher is responsible for doing the context switch when execution
is transferred between two micro-threads.
2. Switcher Object
The switcher object must be constructed in the system thread it intends
running in; and in addition, all switcher methods must be called from
within that same system thread.
The cMicroThreads.pas unit implements two switcher objects.
TFiberSwitcher uses Windows Fibers to do task switching.
Experiments have shown that Windows 2000 can handle in the order of two
hundred fibers per thread.
TWintelSwitcher is a low level implementation for Windows.
It can handle hundreds of thousands of tasks per thread.
2.1 Methods
function Add (
const RunProc : TMicroThreadRunProc;
const StackSize : Integer = -1;
const Data : Pointer = nil ) : TMicroThreadHandle
Call Add to create a new micro-thread. It returns a handle to the new
micro-thread. The micro-thread only starts execution when it is activated
by a call to SwitchTo.
function GetCurrent : TMicroThreadHandle;
GetCurrent returns a handle of the currently executing micro-thread.
When a switcher is created, there exists one micro-thread for the
currently running thread.
procedure Delete (
const Handle : TMicroThreadHandle )
Delete removes a micro-thread previously created by a call to Add.
The initial thread and the currently running thread can not be deleted.
procedure SwitchTo (
const Handle : TMicroThreadHandle )
function GetPrimary : TMicroThreadHandle
function GetCount : Integer
3. Flow of execution
A call to SwitchTo is invalid to a terminated micro-thread. A micro-
thread terminates when it returns normally or when an exception is
raised. When a thread terminates, control is returned to the primary
micro-thread. When an exception is raised in a non-primary micro-thread,
the exception is re-raised in the primary micro-thread. The primary
micro-thread follows normal exception handling and flow of execution
rules.
Because the primary micro-thread never terminates, and because execution
returns to the primary micro-thread when other micro-threads terminate
or raise an exception, it is useful to use the primary thread as a
scheduler for the other threads.
4. Examples
4.1 Using the switcher object directly
uses cMicroThreads;
var Switcher : TWintelSwitcher; // The switcher object
T1, T2 : TMicroThreadHandle; // Handles to Task1 and Task2
procedure Task1(const Data: Pointer);
begin
Writeln('Task1.1');
Switcher.SwitchTo(T2); // Switch to Task2
Writeln('Task1.2');
Switcher.SwitchTo(T2); // Switch to Task2
end;
procedure Task2(const Data: Pointer);
begin
Writeln('Task2.1');
Switcher.SwitchTo(T1); // Switch to Task1
Writeln('Task2.2');
end;
begin
Switcher := TWintelSwitcher.Create; // Create switcher object
T1 := Switcher.Add(Task1); // Add Task1 and save handle
T2 := Switcher.Add(Task2); // Add Task2 and save handle
Switcher.SwitchTo(T1); // Switch to Task1
Writeln('Fin'); // Returns here when tasks complete
Switcher.Free; // Destroy switcher object
end.
The output of the above code will be:
Task1.1
Task2.1
Task1.2
Task2.2
Fin
|