Процессы, выполняемые на разных процессорах мультикомпьютера, обычно общаются между собой с использованием модели обмена данными посредством передачи сообщений. Имеется два варианта организации связи между процессами посредством передачи сообщений:
Системные вызовы типа send и receive.
Различают блокирующие вызовы (синхронные вызовы) и неблокирующие вызовы (асинхронные вызовы).
Обмен сообщениями между процессами с использование блокирующих вызовов происходит по следующей схеме:
Если вызов является неблокирующим, то он возвращает управление вызывающему процессу до завершения отправки сообщения (см. рис. 1б).
Аналогично, неблокирующий вызов возвращает управление вызывающему процессу до завершения получения сообщения. Преимущество неблокирующих вызовов состоит в том, что процессы, осуществляющие эти вызовы, могут работать параллельно с обменом сообщениями.
Рис. 1.  а) Схема блокирующего вызова send. В течение периода времени [t1,t2] процесс Q1 заблокирован, происходит отправка сообщения. б) Схема неблокирующего вызова send. В течение периода времени [t1,t3] процесс Q1 заблокирован, ОС обрабатывает прерывание, вызванное вызовом. В течение периода времени [t3,t4] происходит отправка сообщения.
Реализации неблокирующих вызовов send значительно сложнее реализации блокирующих вызовов. Дело в том, что в изложенной схеме процесс-отправитель сообщения не знает, когда отправка сообщения завершена и когда можно повторно использовать область памяти, в котором хранилось отправляемое сообщение.
Возможно несколько решений этой проблемы.
  1. Копирование сообщения в буфер ядра ОС. Недостатком данного решения является необходимость наличия дополнительных буферов для вызовов, а также необходимость лишнего копирования, что может существенно снизить производительность системы.
  2. Прерывание процесса-отправителя в тот момент, когда отправка сообщения завершена. Это решение значительно усложняет программу пользователя, поскольку требует обработки в ней указанных прерываний
  3. Копирование сообщения в буфер ядра ОС только в том случае, когда процесс пытается повторно использовать область памяти, в которой хранится сообщение. Данное решение может потребовать неоднократного копирования указанной области памяти (если процесс формирует очередные вызовы send до завершения отправки предыдущих сообщений).
Аналогично, реализации неблокирующих вызовов receive вызывает серьезные проблемы. Процесс-получатель может информироваться о завершении приема сообщения с помощью прерывания. Однако, опять же, эти прерывания программе пользователя необходимо обрабатывать. Другим решением является создание для каждого процесса своего «почтового ящика». ОС записывает поступающие сообщения в этот почтовый ящик, а программа пользователя периодически опрашивает его на предмет наличия непрочитанных сообщений. Используются и другие решения.
Замечание. Для процессов, которые взаимодействуют в компьютерной сети в соответствии с семейством протоколов TCP/IP, операционная система Unix использует программные гнезда (sockets). Взаимодействие процессов на основе программных гнезд основано на модели "клиент-сервер". Операционная система поддерживает внутренние соединения и маршрутизацию данных от клиента к серверу.
Вызов удаленной процедуры.
Часто обмен данными между процессами носит ярко выраженный асимметричный характер: один из процессов (процесс-клиент) запрашивает у другого процесса (процесс-сервер) некоторую услугу (сервис) и не продолжает свое выполнение до тех пор, пока эта услуга не будет выполнена и пока процесс-клиент не получит соответствующие результаты. Семантически такой режим взаимодействия процессов эквивалентен вызову процедуры. Поэтому естественно желание оформить его должным образом и синтаксически.
С точки зрения прикладной программы вызов удаленной процедуры (remote procedure call) происходит по следующей схеме:
Информация между процессом и вызываемой процедурой передается через параметры процедуры (как в традиционных языках программирования).
Реализация вызова удаленной процедуры:
ОС клиентского процессора упаковывает параметры в сообщение и с помощью системного вызова d отправляет сообщение серверному процессору. ОС серверного процессора с помощью системного вызова принимает параметры, распаковывает их и передает процессу-серверу.
Аналогично, при передаче процессом-сервером результатов выполнения процедуры процессу-клиенту (см. рис. 3) ОС серверного процессора упаковывает результаты в сообщение и с помощью системного вызова отправляет сообщение клиентскому процессору. ОС клиентского процессора с помощью системного вызова принимает результаты, распаковывает их и передает процессу-клиенту.
Поскольку в различных компьютерах мультикомпьютера данных могут представляться по-разному (например, часто по-разному представляются числа с плавающей точкой), то одной из основных функций данного механизма обмена сообщениями является автоматическое преобразование форматов данных при взаимодействии процессов, выполняющихся на разнородных компьютерах.
Рис. 2.  Передача процессом-клиентом Qi параметров процедуры процессу-серверу Qj.
Рис. 3.  Передача процессом-сервером Qj результатов выполнения процедуры процессу-клиенту Qi.
При идейной простоте изложенной схемы реализация этой схемы сталкивается с рядом проблем.
Во-первых, поскольку процесс-клиент и процесс-сервер находятся в разных адресных пространствах, невозможно использование указателей в качестве параметров. В некоторых случаях эту проблему можно обойти, передавая процессу-серверу не указатель, а сами данные, на которые ссылается этот указатель. Если данные имеют сложную структуру, этот метод практически неработоспособен. Аналогичная ситуация имеет место также и при использовании системных вызовов типа и .
Во-вторых, если язык программирования пользовательского процесса не является сильно типизированным, то не всегда ОС процесса-клиента может передать процессу-серверу все необходимые данные. Такая ситуация, например, может иметь место, если количество элементов массива определяется не его описанием, а ограничивается каким-либо специальным символом.
В-третьих, локальная процедура наряду с параметрами, передаваемыми через ее заголовок, может использовать глобальные параметры. Удаленная процедура из-за разных адресных пространств процесса-клиента и процесса-сервера не может использовать глобальные переменные процесса-клиента.
Вызов удаленной процедуры может быть реализован с помощью системных вызовов или библиотечных функций.