Inter-process Communication

A process is an instance of a computer program that is currently being executed by one or more threads. Processes can be one of two types, either independent or cooperating. An independent process is not affected by the execution of other processes as they do not share data with any other process. A cooperating process can be affected by other executing processes because the do share data with other processes.

Inter-process communication is the act of exchanging data between two or more separate processes.

Facilities of Inter-process Communication

  • Operating systems provide facilities/resources for inter-process communications (IPC), such as message queues, semaphores, and shared memory.
  • Distributed computing systems make use of these facilities/resources to provide application programming interfaces (APIs) which allows IPC to be programmed at a higher level of abstraction. (e.g., send and receive).
  • Distributed computing requires information to be exchanged among independent processes.

Types of IPC

Communications between processes can be done in either shared memory or via message passing.

Shared Memory IPC

Shared memory refers to the physical memory mapping. With shared memory IPC the data in memory is directly accessible to each process in their respective address spaces.

Shared memory inter-process communications are generally faster than message passing implementations due to the fact that the memory that is shared is generally closer to the cpu executing the processes and only requires the establishment of shared-memory regions.

A process creates the shared-memory region in it’s own address space while other processes communicate by attaching the address space to it’s own address space. Processes communicate by reading and writing data in the shared area. The operating system does not have any control over this data or it’s location. This is solely determined by the processes.

A very famous problem called “Producer-Consumer Problem” is used to illustrate the inner workings of shared memory systems. A brief explication of the producer-consumer problem follows:

  1. A producer process produces information that is to be consumed by the consumer process.
  2. By shared memory, both producer and consumer share a memory space called a buffer.
  3. A producer produces an item at a time and a consumer consumes another item at that time.
  4. Both producer and consumer are synchronized so that consumer does not consume an item that has not yet been produced.

A simple example of this problem is found in the Client-Server system. Considering the server as the producer and the client as the consumer. A web server, for example, produces web content such as HTML files and images which are consumed by hte client web browser.

2 types of buffers can be used in the: a bounded buffer which uses a fixed buffer size or an unbounded buffer which has no limits on its size.

Message Passing IPC

Message Passing involves the marshaling of data to and from a process via a communication link. This data is generally refereed to as messages. Message passing inter-process communication also provides a means to synchronize processes without sharing a memory space. This form of IPC is useful when the processes reside on different computers and are connected by a network.

Message passing inter-process communication is useful for exchanging smaller amounts of data across processes that are distributed across a network though it requires the more time consuming task of kernel intervention to handle data forwarding.

Messages, like buffers in the Client-Server system, can be either fixed size or variable size and can use a combination of operations to facilitate message passing.

  1. Direct and indirect communication

In direct communication, each task explicitly passes the message along with passing the name of the process to which it is passing. As follows:

send(task_name, message)
receive(task_name, message)

In indirect communication, message passing is through “mailboxes” where each task communicating should have a shared mailbox.

send(mailbox_name, message)
receive(mailbox_name, message)
  1. Synchronous and asynchronous communication

Tasks make calls to each other for communication between processes. Synchronous, in this case means process blocking and asynchronous means process non-blocking.

There are five (5) cases, or states, that could occur:

Blocking send

The sending process is blocked until the message is received by the receiver task.

Non-blocking send

The sending process sends the message according to it’s requirement without considering whether the message is received or not at the receiver’s end.

Blocking receive

The receiving process is blocked until a message is available.

Non-blocking receive

The receiving process goes on accepting either the message or null information continuously.

Blocking send and receive

Both the sending and receiving process are blocking, this is a special case called a “rendezvous”.

Buffering

The messages to be exchanged resides in a temporary queue. It can be implemented in one (1) of three (3) ways:

Zero capacity

A zero capacity queue limits the maximum length of the queue to zero. This means that messages cannot be enqueued. They are sent out and the sender will be blocked until the receiver receives the message.

Bounded capacity

A bounded capacity queue has a finite length, at most a finite number of messages will only reside in the queue. The sender can send messages until the queue is empty.

Unbounded capacity

An unbounded capacity queue has a theoretically infinite length. Any number of messages can be enqueued, waiting to be processes. The sender is non-blocking.

Pipes

Pipes act as a channel between two (2) processes to communicate.these were one of the first IPC mechanisms in early UNIX. Pipes allow a mechanism in which output of one process is used as input of another process. Pipes function as a first-in-first-out (FIFO) and there are two (2) types of pipes:

Ordinary pipes

Ordinary pipes allow for communication in producer-consumer systems. The producer writes to one end, and the consumer reads from the other. It allows for only unidirectional flow of data. For 2-way communications, there must be two (2) ordinary pipes. On Windows operating systems, ordinary pipes are termed “Anonymous” pipes and the communicating processes have a parent-child relationship. These can be used only for communication between processes on the same machine. Once processes finish, ordinary pipes cease to exist.

Named pipes

Named pipes can be bidirectional, requiring no parent-child relationship and is used for communication between several processes. These pipes continue to exist even after communicating processes have finished. Named pipes are FIFO in UNIX.

Sockets

Sockets also enable channel-based communication for processes on the same device. But network sockets allow IPC between processes on different hosts via networking protocols. A socket consists of an internet protocol (IP) address and a port number.

Generally socket use a client-server architecture. The server here waits for a client request by listening to a specified port. After receiving the request, the server accepts the connection and connection is completed. The client proces has a port assigned to it by the host computer

For example, a client on host ‘A’ with the IP address 130.44.3.60 wishes to establish a connection with a web server which is listening at port 70 at address 151.33.50.9.

Semaphores

Semaphores are used to lock and unlock the critical regions that are shared among processes. If a single region is shared by multiple processes, there is a possibility for a deadlock. Semaphores come into play to manage message passing in such situations. Semaphores can generally be of one of two (2) types, either binary semaphores or counting semaphores. Binary meaning having two (2) *states where as counting semaphores keep a counter.

A very basic example for implementation of semaphores is the case for printing. Suppose that there are five (5) printers. These printers share their jobs between each other. We request to print three (3) documents, so the server receives three (3) print jobs. These jobs will be given to three (3) printers. Another four (4) jobs are sent to the printers while the previous batch was executing. The two (2) free printers will schedule two (2) of the four (4) jobs and the other two (2) will be executed when there are free printers to do so. This is how counting semaphores are implemented. Semaphores manage the entry and exit of processes into a critical section (a section of a program or memory that multiple processes interact with).

Unicast and Multicast

Unicast is an attribute of IPC specifying that the communication is from one process to another single process (e.g., Socket communication) while multicast is from one process to many other processes (e.g., Publish/Subscribe messaging model)

Event Synchronization

Inter-process communications may require that the communicating processes synchronize their operations with each other. Such as when one process sends data to the other(s) and the other(s) wait until all the data has been received. Ideally, the send operation will start before the receive operation does and finish before the it as well. In practice, these synchronizations require system support.

Synchronous and Asynchronous Communication

IPC operations may provide the synchronization necessary, given system support, by using blocking operations issued by a process that will block further processing of the process until the operation that is blocking is fulfilled. Alternatively,

IPC operations may asynchronous or non-blocking. An asynchronous operation issued by a process will not block further processing of the process. Instead, the process is free to proceed with its processing, and may optionally be notified by the system when the asynchronous operation is fulfilled.

Deadlocks and Timeouts

Blocking operations issued in the wrong sequence can cause deadlock. Timeouts can be used to detect deadlocks. Connect-and-receive operations can result in indefinite blocking. For example, a blocking connect request can result in the requesting process being suspended indefinitely if the connection is unfulfilled or cannot be fulfilled, perhaps as a failure or malfunction in the network. It is generally unacceptable for a requesting process to “hang” indefinitely.

Indefinite blocking can be avoided by using using timeouts or non-blocking operations.

IPC Paradigms and Implementations

Paradigms of IPC of different levels of abstraction have evolved, with corresponding implementations.

IPC Paradigms

  • Remote Procedure/Method
  • Socket API
  • Data Transmission

IPC Implementations

  • Remote Procedure Call (RPC)
  • UNIX Socket API, Winsock
  • Serial/Parallel Communications

Differences Between Function Callbacks and Inter-Process Communications

A function callback is the act of supplying the address, or some other identifier, of a function to another function so that it can be called back into the supplied functions scope for some reason.

IPc, on the other hand, is a means for processes to commuticate with each other, such as shared memory, pipes, semaphores, etc…

Some IPC mechanisms may use callbacks but it’s by no means necessary. For example, sockets don’t use callbacks, they simply allow allowa user to call read and write methods.