.. _IPCModels:

.. raw:: html

   <script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "IPCModels";ODSA.SETTINGS.MODULE_LONG_NAME = "IPC Models";ODSA.SETTINGS.MODULE_CHAPTER = "Concurrency with IPC"; ODSA.SETTINGS.BUILD_DATE = "2021-06-01 12:51:47"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script>


.. |--| unicode:: U+2013   .. en dash
.. |---| unicode:: U+2014  .. em dash, trimming surrounding whitespace
   :trim:


.. This file is part of the OpenCSF eTextbook project. It was
.. auto-generated by scripts from the OpenDSA eTextbook project.
.. See https://OpenCSF.org for more details. OpenCSF is distributed
.. under a Creative Commons Attribution-NonCommercial 4.0 International
.. License (see http://creativecommons.org/licenses/by-nc/4.0/),
.. Copyright (c) 2019-2021 by Michael S. Kirkpatrick. OpenDSA is
.. distributed under an MIT open source license, Copyright (c) 2012-2021
.. by the OpenDSA Project Contributors.

.. avmetadata::
   :author: Michael S. Kirkpatrick
   :requires: IPC Overview
   :satisfies: IPC Models
   :topic: Message Passing, Shared Memory, IPC Taxonomy

IPC Models
==========

There are multiple ways that different forms of IPC can be classified. The first and most common
distinction is to separate techniques that adhere to a :term:`message passing` model from a
:term:`shared memory` model. In message passing, whenever a piece of data is to be exchanged, the
process will invoke the kernel with a request to send the information to the target process. That
is, the user-mode process will copy the data into a buffer or other form of data structure, then
issue a :term:`system call` to request the data be transferred. Once the kernel is invoked, it will
copy the transferred data first into its own memory. At some later point, the target process will
also issue a system call to retrieve the data. In short, message passing techniques require the
kernel become involved in every distinct exchange of data.

Shared memory techniques work fundamentally differently than message passing. In shared memory, the
processes initially set up a region of their virtual memory to use for the IPC. Once the region is
established within the process, the process issues a system call to request that the kernel make the
region shared. Other processes would do the same. After the initial system call to set up the shared
memory, the processes can read from and write to the region just as it would access non-shared data
on its own heap. That is, the process could write to the region by dereferencing a pointer to it.
This data then appears within the context of the other process automatically. There is no explicit
system call required to read the new data.


Advantages and Disadvantages
----------------------------

Message passing and shared memory both have advantages and disadvantages relative to each other. One
key dimension for comparing their performance is the amount of time overhead required. In message
passing, every piece of data exchanged requires two system calls: one to read and one to write. In
addition, the transferred data must be copied twice: once into the kernel memory and once into the
receiving process. For a single message, this time penalty is insignificant and is unlikely to
affect the process's performance. However, if the number of messages passed is extremely large, the
cumulative effect of this penalty may be significant.

In contrast, shared memory techniques only require a one-time performance penalty during the set-up
phase. Once the memory has been shared, there is no additional penalty, regardless of the amount of
data transferred. The trade-off is that the penalty for setting up shared memory is significant. The
kernel must perform several slow operations to link the shared region to all of the processes'
virtual memory spaces.

Overall, if the two processes will be exchanging a lot of data back and forth repeatedly, shared
memory performs very well. While the work to set up the shared memory is expensive, the aggregate
effect of the performance is reduced. However, if processes only need to exchange a single message
of a few bytes, shared memory would perform very poorly. Message passing techniques impose
significantly smaller overhead to set up a one-time data exchange.

Shared memory also has another disadvantage that message passing avoids, which is the problem of
:term:`synchronization`. If both processes try to write to the shared memory region at the same
time, the result would be unpredictable and could lead to errors in one or both processes.
Consequently, the accesses must be synchronized, meaning that the timing is carefully controlled.
Since all message passing exchanges go through the kernel, synchronization techniques are not necessary.

As an example of the synchronization problem, consider an example where the two processes are
keeping track of money in your bank account. One process writes a record for a \\$100 purchase that
you made, while another records a \\$100 deposit. If both are recorded correctly, your new balance
should be the same as when the processes started. However, if the account record is in shared memory
and the writes are not properly synchronized, the results may not be correct. Instead of your final
balance being exactly what you started with, you may end up with \\$100 more or less than your
original balance. Either you or your bank would be very unhappy with this result. Synchronization is
a complex topic and we discuss it in its own chapter.

An IPC Taxonomy
---------------

There are several different IPC techniques that can be used for a variety of different purposes. In
`The Linux Programming Interface` [Kerrisk2010]_ , Kerrisk provides a taxonomy of UNIX IPC that is
useful for classifying these techniques along a number of different dimensions. These dimensions
include which model (shared memory or message passing), the primary intended purpose (data exchange
or synchronization), and the granularity of the communication (byte stream or structured messages).
We could also add a distinction between network-based or local to a single machine. `Table 3.1 <#tbl3-1>`_
shows this taxonomy.

Before summarizing the taxonomy, we note that the term *shared memory* has two meanings in IPC that
can cause some confusion. As we described above, shared memory is a general model that refers to the
fact that the IPC occurs in a region of memory that is co-present within the multiple processes.
Shared memory also refers to a specific technique for creating these regions; this technique uses
library functions that begin with shm, such as ``shmat()`` or ``shm_open()``. There are other shared
memory techniques that rely on other functions. As an example, memory-mapped files are a form of
shared memory that also copies all data into persistently stored files; data shared with ``shm``
functions only exists in memory. To avoid this collision of terminology, we will use ``shm()`` when
referring to the specific techniques while reserving the term *shared memory* for the more general model.

.. _tbl3-1:

.. raw:: html

   <center>
   <div class="row">
   <div class="col-md-12">
     <table class="table table-bordered">
       <thead class="jmu-dark-purple-bg text-light">
         <tr>
           <th class="py-0 center">Technique</th>
           <th class="py-0 center">Model</th>
           <th class="py-0 center">Purpose</th>
           <th class="py-0 center">Granularity</th>
           <th class="py-0 center">Network</th>
         </tr>
       </thead>
       <tbody>
         <tr>
           <td class="py-0 center">pipe/FIFO</td>
           <td class="py-0 center">message passing</td>
           <td class="py-0 center">data exchange</td>
           <td class="py-0 center">byte stream</td>
           <td class="py-0 center">local</td>
         </tr>
         <tr>
           <td class="py-0 center">socket</td>
           <td class="py-0 center">message passing</td>
           <td class="py-0 center">data exchange</td>
           <td class="py-0 center">either</td>
           <td class="py-0 center">either</td>
         </tr>
         <tr>
           <td class="py-0 center">message queue</td>
           <td class="py-0 center">message passing</td>
           <td class="py-0 center">data exchange</td>
           <td class="py-0 center">structured</td>
           <td class="py-0 center">local</td>
         </tr>
         <tr>
           <td class="py-0 center">shm()</td>
           <td class="py-0 center">shared memory</td>
           <td class="py-0 center">data exchange</td>
           <td class="py-0 center">none</td>
           <td class="py-0 center">local</td>
         </tr>
         <tr>
           <td class="py-0 center">memory-mapped file</td>
           <td class="py-0 center">shared memory</td>
           <td class="py-0 center">data exchange</td>
           <td class="py-0 center">none</td>
           <td class="py-0 center">local</td>
         </tr>
         <tr>
           <td class="py-0 center">signal</td>
           <td class="py-0 center">message passing</td>
           <td class="py-0 center">synchronization</td>
           <td class="py-0 center">none</td>
           <td class="py-0 center">local</td>
         </tr>
         <tr>
           <td class="py-0 center">semaphore</td>
           <td class="py-0 center">message passing</td>
           <td class="py-0 center">synchronization</td>
           <td class="py-0 center">none</td>
           <td class="py-0 center">local</td>
         </tr>
       </tbody>
     </table>
     <p>
     Table 3.1: Classifying standard IPC techniques based on several characteristics
     </p>
   </center>

Although :term:`signals <signal>` are covered in another chapter, we include them in this taxonomy
because they can be interpreted as a limited form of IPC. Signals do not include any data and they
are received asynchronously by the destination process. As such, they are very limited in the
information they are conveying; they simply alert another process of a particular type of
pre-defined event. However, this can be interpreted as a form of IPC.

:term:`Sockets <socket>` are a flexible form of message passing IPC that can be used in multiple
ways. The most common way that sockets are used is to send data across a network connection. As
such, we will not consider sockets in this chapter and will explore their uses when discussing
networks.

.. avembed:: Exercises/IPC/IPCModelSumm.html ka
   :module: IPCModels
   :points: 1.0
   :required: True
   :exer_opts: JXOP-debug=true&amp;JOP-lang=en&amp;JXOP-code=java
   :long_name: IPC models questions
   :threshold: 3

