[DBPP] previous next up contents index [Search]
Next: 6.6 Determinism Up: 6 Fortran M Previous: 6.4 Unstructured Communication

6.5 Asynchronous Communication


  Recall that the need for asynchronous communication can arise when the   tasks involved in a computation must access elements of a shared data   structure in an unstructured manner (Section 2.3.4). One implementation approach is to encapsulate the data structure in a set of specialized data tasks to which read and write requests can be directed. This approach is easily implemented using FM constructs: for example, the process structure illustrated in Figure 6.4 could be used to connect four computation tasks with three data tasks.

An alternative implementation approach is to distribute the   shared data structure among the computation tasks. Individual computation tasks must then poll periodically for pending read and   write requests. This approach is supported in FM by the PROBE   statement, which allows a process to determine whether messages are pending on the channel or merger associated with an inport. This is a potentially nondeterministic operation, since the result returned by a PROBE statement can vary depending on the time at which it is executed. A PROBE statement has the general form

PROBE( inport, empty= logical )

and sets the logical variable named by the empty specifier to true if the channel is empty (meaning a RECEIVE on the inport would block) and to false otherwise.

Optional iostat= and err= specifiers can be included in the control list; these are as in the Fortran inquire statement. Hence, applying a PROBE statement to an undefined port causes an integer variable named in an iostat specifier to be set to a nonzero value and causes execution to branch to a label provided in an err= specifier.

Knowledge about send operations is presumed to take a nonzero but finite time to become known to a process probing an inport. Hence, a probe of an inport that references a nonempty channel may signal true if a value was only recently communicated. However, if applied repeatedly without intervening receives, PROBE will eventually signal false and will then continue to do so until values are received.

The PROBE statement is useful whenever a process needs to interrupt local computation to handle communications that arrive at some unpredictable rate. For example, the following code might be used in an implementation of the branch-and-bound search algorithm of Section 2.7.

		 inport (T) requests   						 ! T an arbitrary type

logical eflag

do while (.true.) ! Repeat:

call advance_local_search ! Compute

PROBE(requests,empty=eflag) ! Poll for requests

if(.not. eflag) call respond_to_requests


This code fragment alternates between advancing a local search and responding to requests for search problems from other processes.



The PROBE statement can also be used to receive data that arrive in a nondeterministic fashion from several sources. For example, Program 6.7 handles messages of types T1 and T2 received on ports data1 and data2, respectively. A disadvantage of this program is that if no messages are pending, it consumes resources by repeatedly probing the two channels. This busy waiting strategy is acceptable if no other computation can be performed on the processor on which this process is executing. In general, however, it is preferable to use a   different technique. If T1=T2 , we can introduce a merger   to combine the two message streams, as follows. The handlemsgs2 process then performs receive operations on its single inport, blocking until data are available.

    MERGER(in=datai, out=data1o, out=data2o)
       PROCESSCALL source1(data1o)
       PROCESSCALL source2(data2o)
       PROCESSCALL handlemsgs2(datai)

[DBPP] previous next up contents index [Search]
Next: 6.6 Determinism Up: 6 Fortran M Previous: 6.4 Unstructured Communication

© Copyright 1995 by Ian Foster