Inter-process Communication (IPC)

Objects in a non-distributed application reside in the same address space. This makes communication easy. Object A communicates with object B simply by calling B's member functions. Distributed objects have process or machine boundaries between them. Communicating across such boundaries requires some help from the underlying platform and network. There are two styles of inter-process communication: shared memory and message passing.

Message Passing

In direct communication message passing every pair of processes has a communication link between them:

class Link {
   void send(Process p, Message m) {
      // send m to p
   }
   void send(Message m) {
      // send m to all
   }
   Message receive(Process p) {
      // receive message from p
   }
   Message receive() {
      receive a message from anyone
   }
}

In indirect communication processes leave message for each other in shared mailboxes:

class Mailbox {
   Queue messages;
   void send(Message m) { messages.enqueue(m); }
   Message receive() {
      return messages.dequeue();
   }
}

In a more elaborate scheme a virtual post office called a message broker can be used.

Synchronization

In synchronous message passing send and receive are blocking operations:

class Link {
   Message send(Process p, Message m) {
      // send m to p
      return p.receive(); // wait for reply
   }
   Message receive(Process p) {
      // block until message from p arrives
   }
}

Buffering

A message queue-- whether a mailbox or a link-- can have capacity 1, bounded, or unbounded.

Shared memory

Distributed applications normally share objects contained in files, databases, and shared memory segments (some operating systems allow programs to link shared memory segments into their address spaces).

Blackboard Architectures

Blackboard architectures provide a more interesting example of shared memory communication. In this architecture distributed objects called contributors communicate by updating a shared object called a blackboard. A moderator object determines the order in which contributors perform these updates. There is even a Blackboard design pattern:

Blackboard Architecture

Problem

In many pattern recognition problems raw data collected by sensors (e.g., sounds, images, telemetry, etc.) must be transformed into high-level data structures (e.g., parse trees, component models, text, etc.). If the semantic  gap between the raw data and the high-level data structures is large, then there may be no deterministic algorithm for performing the transformation. Instead, only algorithms that perform partial transformations may exist, but the order in which these algorithms should be applied isn't known in advance.

Solution

A Blackboard architecture consists of three types of components: a blackboard, a moderator, and one or more contributors. The blackboard is a shared data structure that maintains the application data in different levels. Level 0 contains the raw data itself, while the data at level n + 1 consists of transformations of level n data. The highest level will ultimately contain the high-level data structures that we seek.

A contributor or knowledge source is an independent object that is able to transform some types of level n data into level n + 1 data. Contributors don't communicate directly with each other. Instead, each one examines the blackboard, then makes a proposal for transforming the data. A proposal usually has an accompanying degree of certainty, which is based on the current state of the blackboard.

Proposals are submitted to the moderator or controller. The moderator determines which proposal might move the problem furthest toward an ultimate solution. The moderator selects a proposal, allows the corresponding contributor to update the blackboard, and the cycle repeats. In some cases the moderator may need to backtrack if it determines that the present direction will not lead to the desired solution.

Static Structure

Note: In a distributed architecture possible process or machine boundaries are shown as heavy dashed lines.

Example

HEARSAY II used a blackboard architecture to recognize human speech. In this case the raw data was acoustical data which was to be transformed into a database query. Contributors existed for transforming acoustical data (level 0, wave forms) into phonetic data (level 1, phonemes), phonetic data into lexical data (level 2, words), lexical data into syntactical data (level 3, phrases), and syntactical data into queries (level 4).

Synchronization

Although shared memory communication is easy and efficient, synchronization is a significant problem. We can predict execution order within a process, but we cannot predict execution order when the instructions are executed by different processes. For example, object A in process #1 may check a shared data structure before object B in process #2 has had a chance to make an important message. Thus, object A misses the change.

Shared memory communication requires some type of synchronization mechanism to force object A wait until object B's change is made. (This was the job of the moderator in the Blackboard architecture.)

Examples

Examples

Sockets

If objects A and B are separated by a machine boundary, then they must communicate with each other by sending messages across a network. The simplest method is to equip A and B with connected sockets. A socket is basically a transceiver. A transceiver combines a transmitter (an object that can be used to send or transmit messages) with a receiver (an object that can receive messages). Telephones, CB radios, and mailboxes are examples of transceivers. Of course a transceiver is only useful if it is connected to another transceiver in such a way that messages sent by one are received by the other and vice versa.

 

class Socket {
   public Socket(String host, int port) { ... }
   public InputStream getInputStream() { ... }
   public OutputStream getOutputStream() { ... }
   // etc.
}

Example: A Date Client

Most standard Internet servers— ftp servers, telnet servers, web servers, etc.— perpetually listen for clients at well known port numbers below 100. For example, most computers are equipped with a date server that listens for clients at port 13. When a connection is made, the date server sends the local date and time to the client.

import java.util.*;
import java.io.*;
import java.net.*;

public class DateClient {
   protected Socket sock;
   protected BufferedReader sockin;
   protected PrintWriter sockout;
   public DateClient(String host) { ... }
   String getDate() throws IOException {
      return sockin.readLine();
   }
   public static void main(String[] args) {
      try {
         DateClient client = new DateClient("localhost");
         System.out.println(client.getDate());
      } catch (IOException ioe) {
     
      }
   }
}

   public DateClient(String host) {
      try {
         Socket sock = new Socket(host, 13);
         sockin = new BufferedReader(
                  new InputStreamReader(
                     sock.getInputStream()));
         sockout = new PrintWriter(
                  sock.getOutputStream(), true);
      } catch(UnknownHostException uhe) {
         System.err.println("unknown host " + uhe);
         System.exit(1);
      } catch(IOException ioe) {
         System.err.println("failed to create streams " + ioe);
         System.exit(1);
      }
   }

Remote Method Invocation