January 16, 2008 11:42 AM
Usually when you want to simulate or fake multi-thread behavior2, you split your work into chunks and defer processing of the next chunk after a screen update so that the UI doesn't block when you are doing CPU intensive tasks. This situation is pretty common and necessary for the application to be responsive.
Alex Harui has generalized this into PseudoThread and it basically
uses the stage's
RENDER event to defer processing. His code
performs as much Actionscript computation as possible limited by the
time needed to maintain the frame rate.
uses a variant of a mutual exclusion algorithm intended for a system
of multiple threads when the only communication between them is shared
memory. More details are present in the link. The idea of the
algorithm is that all critical section pieces are given a unique
number. Each section waits for jobs that were registered before them
setTimeout(). That is,
all methods run, wait for methods before them to complete via
setTimeout() and then run it's code.
Basically, this "mutex" enforces ordered execution of logical blocks.
Using the above logic, I have written an actionscript class called "PseudoMutex" which complements PseudoThread. Note that this mutex is actually only useful to order the execution of logical units between different threads3. It doesn't actually provide mutual exclusion, instead provides an illusion of ordering execution of code within our existing context switching code. If there was no pseudo thread, there would be no need for pseudo mutex.
The example (view source enabled) below tries to illustrate visually the working of the pseudo mutex:
There are 2 demos in the example. Both of them have 3 textarea components being updated with data (incremented counter from a shared source) via 3 pseudo thread functions. Pseudo mutexes are used to ensure the order in which the pseudo thread slices control to each thread function.
- The barrier demo shows how the pseudo mutex can be used to ensure that one thread checks for a shared value before the other. Thread 3 waits for thread 2 to reach a particular count and thread 1 only starts checking for a higher count once thread 3 has completed it's critical section.
- The ordering demo uses pseudo mutexes to ensure that the third thread gets first control (i.e number 1 from shared data source) and then control is passed to the first thread and finally to the thread. This order is entirely dependent on the order in which the critical sections were registered with the mutex.
Note: The pseudo thread code has been modified so that only one computation happens before a screen update. This is for demo purposes only.
The pseudo thread calls the registered thread function till the function returns a value indicating that they have completed. The order in which the thread functions execute depends upon the order in which the constructor of pseudo thread was called. Apart from this, we have no control over when a particular thread function should get called. This is the deficiency that the pseudo mutex attempts to address.
The pseudo mutex returns false when it is not the right time for it to execute it's code. Then, the function in the pseudo thread also returns true indicating that the thread wants to yield. This is continued till the critical section is executed after which the pseudo thread can yield and resume work in it's own style.
Multiple mutexes are supported and each will have it's own queue of critical sections which get executed in order.
Visualizing the critical section in this is so drastically different from how you think of it in C or C++ that I'm not sure about how useful this code will be. Any feedback is appreciated.
 Another common cause for confusion is
developers don't realize that your event handlers will get called
immediately when a
dispatchEvent() is called.
 This sort of fake multi-threading was even possible in the old days of DOS C code. You could save your point in code using a
and do a non-local jump back to the same point via
and restoring all the registers along the way.
 Thread = Pseudo Thread.