The main method of communication between child and parent tasks is through explicit
'signal' events. This mechanism allows
the child task to send a message to the parent, and vice versa. This works as
follows:
In both cases, the Signal method optionally takes an
argument, which is any APL array (or an APLX overlay created using ŚOV). This is typically used to send a command to the other task, or to return
a result to it. Any argument to the Signal
method is available to the receiving task as the ŚWARG system variable during the execution of the callback.
For example, suppose a child task is being used to carry out a time-consuming
calculation. It starts by awaiting a
signal to indicate that it should do the calculation, with the argument to the
signal being the data to work on. When
it has completed the calculation, it sends a signal back to the parent with the
answer. The following sequence
indicates how this might be done.
First we need to do some setup. The parent task attaches a callback to the child task
object:
’CALCDONE [1] 'The answer is ' ŚWARG ’ ChildTask.onSignal„'CALCDONE'
This will cause the CALCDONE function to be run when
the child task signals that it has a result available, and the result will thus
be printed.
Similarly, the child task attaches a callback to its System object, waiting for a signal
to indicate that it should carry out the calculation:
’DOCALC;RESULT;DATA [1] DATA„ŚWARG [2] RESULT„RUNMODEL DATA [3] '#' ŚWI 'Signal' RESULT ’ '#' ŚWI 'onSignal' 'DOCALC' ŚWE Ż1
This will cause the DOCALC function to be run when the
parent signals the child, using the data passed as the argument to the Signal
method. When the calculation is
complete, the child signals back to the parent. The child then sits in the ŚWE event
loop waiting for signals to occur (this takes no CPU resource).
To carry out the calculation, the parent signals the child, and then processes
events (if it is not already running under ŚWE):
ChildTask.Signal THEDATA ŚWE Ż1
This triggers the child task to run the DOCALC
function, and on completion the parent's CALCDONE function runs:
The answer is 42
In a real example, the parent task would be responding to other events (for example,
user-interface events), and there might be a number of child tasks each
simultaneously working on a different run of the model. If you have multiple child tasks running,
you can use the task ID (ŚEV[6] in index
origin 1) to distinguish between them in the callback function.
There might also be a queue of signals waiting to be processed on either side. Note
that there is a limit to the number of events which can be queued, typically
around 200 events. If this maximum is
exceeded, the oldest events are thrown away.