13.3.2.2. Asynchronous Messages

Consider two tasks that wish to communicate: task E and task F. Task E is a time sensitive task that needs to deliver a package of data to task F. Task E cannot take the chance that task F will accept its data immediately and issue a reply so that it may continue with its own jobs. In short, a synchronous send compromises task E's job because it must wait for task F to respond before proceeding.

To send data asynchronously from task E to task F, a queue is used. Data is sent from task E to the queue. The queue responds immediately to task E, freeing it up to continue. Then a proxy, a special non-blocking message, is sent from the queue to task F. Upon receipt of the proxy, task F knows that the queue contains data for it. When task F is ready it asks the queue for the data.

With some small changes, the example from the previous section can be changed from synchronous messaging to asynchronous, as follows:

Task E:

#!/usr/cogent/bin/gamma
init_ipc("task_e","task_e_q");

add_set_function(#x,#princ("Task E reports x=",x,"\n"));

while (t)
{
    next_event();
}
		

Task F:

#!/usr/cogent/bin/gamma
init_ipc("task_f","task_f_q");

function inc_x ()
{
    local result,tp;

    x++;

    if (tp = locate_task("task_e",nil))
    {
        result = send_async(tp,list(#setq, #x, x));
        princ("task F result of send: ",result,"\n");
    }
}

x = 0;
every(0.1,#inc_x());

while (t)
{
    next_event();
}
		  

The init_ipc function calls at the beginning of each module now open a queue name with qserve, and the inc_x function has been changed to use send_async instead of send.

When this example is run the results show that task F receives a t (true) that the message was delivered but does not have to wait for task E to generate the result of the expression.

Using asynchronous communication immediately solves the dead-lock problem that all developers of multi-module systems must eventually face. To the developer, the use of asynchronous communication in Gamma entails only the use of a slightly different function: send_async instead of send.