Aztec® Programming Language
Version 1.1 Alpha 2

Copyright © 2010-2017, Aztec Development Group, All Rights Reserved

Download Aztec

Search        Contact Us

And the men who could not fight...

In a war... that didn't seem right.

You let 'em come home... America.

- Sammy Johns

 

Creating and Using Multiple Threads

The main thread for the script/application is created automatically by the Virtual Machine, but the user code can create as many additional threads as it needs. The process of creating and executing a new thread is very simple.

♦ Create a new class that is derived from ‘Thread’.

♦ Create at least one constructor.

♦ Create the virtual Run() method that overrides the Thread class implementation.

To manually execute a new thread.

♦ Create an instance of the new thread class using “new<>”.

♦ Invoke the new thread by calling “Run()”.

Note that the constructor for the new thread gets executed during the "new<>" call, so it actually executes within the scope of the calling thread. Execution of the new thread does not begin until Run() is called.

Running multiple threads simultaneously can create some interesting problems and side effects if care is not taken to consider the implications.

♦ If multiple threads try to access an object or a resource simultaneously, the state of the object might become unstable if access to the object is not properly controlled.

Thread Synchronization

Automatic Thread Synchronization

♦ The ‘sync’ keyword can be applied to data items and methods, and the Virtual Machine will ensure that synchronization is automatically performed when using those items.

♦ For a method defined with ‘sync’, the VM will ensure that the method is executed by only one thread at a time. When one or more other threads calls this method while its being executed, each thread gets queued up and waits its turn to execute the method.

♦ This allows the code inside the method perform multiple changes to the state of an object without worrying about another thread interrupting the process half way through.

♦ For a primitive data item defined with ‘sync’, the VM will ensure that only one thread accesses this data item at a time when executing primitive instance methods for the data item (int.Inc(), etc.). The ‘string’ data type is defined as ‘sync’ implicitly. When another thread calls any of the primitive instance methods for this data item, that thread will automatically wait until it’s available. Note that this feature currently only works for global, shared and local data items. Instance data items are not yet supported.

Thread Synchronization Classes

♦ Aztec provides two classes which can be used to synchronize the execution of multiple threads.  They are both defined in the ‘aztec.system’ space.

Class Hierarchy for SyncLock and SyncFlag

 

♦ The ‘SyncLock’ class provides a general purpose mutex/semaphore class. The number of threads which can simultaneously access the resource can be specified in the constructor. A value of one works as a mutex and more than one is a general purpose semaphore class.

♦ This class can be used to protect operations on one or more data items, and it can also be used as a critical section for code.

♦ The ‘SyncFlag’ class provides a simple communication mechanism between threads using a flag. One thread can wait for the flag to be raised, and won’t continue executing until another thread raises the flag.

♦ If you need fancier thread to thread(s) communication, try using SendTextMessage(), SendObjectMessage() or SendBinaryMessage() and setting up corresponding message event handlers in one or more other threads.

♦ Key methods in the SyncLock and SyncFlag classes

Key Methods of SyncLock Class

Key Methods in SyncFlag Class

 

The Aztec source code showing the creation of a child thread with synchronization is shown below.

#===================================================================================================
# Example Script: Aztec Simple Child Thread
# Demonstrates creation of a child thread and simple thread to thread synchronization.
#===================================================================================================

# Main class that is derived from Thread. VM automatically creates us and executes Run().
class Main from<Thread>
{
method Main()
{
# Create the sync flag object so child can tell us when it's done.
ChildDoneFlag = new<SyncFlag>
}

method virtual Run()
{
StdIO.Write("In main thread (Thread " + ThreadId().Str() + "), about to create and execute child thread.")

# Create the child thread, passing it the synchronization flag, and then run it.
Child = new<ChildThread(ChildDoneFlag)>
Child.Run()

# Wait for the child to finish and release this flag.
ChildDoneFlag.WaitForAccess()

StdIO.Write("In main thread, child thread is complete and released control back to us.")
}

data<ChildThread> Child
data<SyncFlag> ChildDoneFlag
}

#-------------------------------------------------------------------------------------
# Child thread that will get created and executed by the Main thread. Once unleashed,
# it runs to completion (simple loop) and then sets flag to tell Main we're done.
#-------------------------------------------------------------------------------------
class ChildThread from<Thread>
{
method ChildThread(SyncFlag DoneFlag)
{
ChildDoneFlag = DoneFlag
}

method virtual Run()
{
data<int> Count = 1
data<int> const Limit = 5000000

StdIO.Write("Child thread (Thread " + ThreadId().Str() + ") is beginning its task.")

# Simply sit in a loop, pretending to be busy, and signal Main when complete.
while ( Count <= Limit )
{
Count.Inc()
}

StdIO.Write("Child thread completed its task (" + Limit.Str() + " loops). Releasing synchronization flag.")

# Main thread can't continue until we release it by raising this flag.
ChildDoneFlag.RaiseFlag()
}

data<SyncFlag> ChildDoneFlag
}

Page UpPage DownCopyright © 2010-2017
Aztec Development Group
All Rights Reserved

Download Aztec