Как происходит обмен данными между процессами через общий файл

Обновлено: 07.07.2024

Взаимодействие процессов - это обмен данными между двумя процессами. В Linux существует несколько способов взаимодействия процессов. В этой статье мы в основном представляем самый простой метод-канал взаимодействия процессов.

Способы коммуникации процесса

Единственный способ обмена информацией между процессами - передача открытых файлов.

Труба

Канал - это одна из старейших и наиболее простых форм системного IPC, все системы Linux предоставляют такой механизм связи. Однако у конвейера есть два следующих ограничения:

  • Это полудуплексный режим, то есть данные по каналу могут передаваться только в одном направлении. Если требуется двусторонняя связь, между двумя процессами должны быть установлены два канала;
  • Каналы могут использоваться только между двумя процессами с общим предком; -

Механизм реализации трубы

Канал - это буфер, которым управляет ядро, один конец которого подключен к выходу процесса, а другой конец подключен к входу процесса. Буфер конвейера не обязательно должен быть большим, он спроектирован как кольцевая структура данных, когда два процесса завершаются, жизненный цикл конвейера также завершается.

Создание конвейера

Канал создается путем вызова функции конвейера.

(pipe1)

Он возвращает два файловых дескриптора по выходному параметру fd,fd [0] открыт для чтения, fd [1] открыт для записи, Выходные данные fd [1] являются входными данными fd [0]. Когда канал создается успешно, функция канала возвращает 0. Если создание не удается, она возвращает -1. Связь между fd [0] и fd [1] показана на рисунке ниже:

Как общаться по трубе


Выше мы установили конвейер в одном процессе, но на самом деле конвейер в одном процессе бесполезен. Обычно процесс сначала вызывает функцию конвейера для создания канала, а затем вызывает функцию fork (). Функция fork изменяет родительский процесс. Соответствующая структура данных наследуется дочернему процессу, так что дочерний процессДескриптор файлаFd [0] и fd [1] в таблице указывают на файл конвейера, на который указывает родительский процесс, так что связь между двумя процессами может быть реализована. Вышеупомянутый процесс выглядит следующим образом:

Связанные правила использования трубопроводной связи

Для конвейера от дочернего процесса к родительскому процессу (запись дочернего процесса, чтение родительского процесса) родительский процесс закрывает fd [1], дочерний процесс закрывает fd [0], когда часть конвейера закрывается (закрывается на основе вышеизложенного Один конец трубы) Работают следующие два правила:

  1. При чтении канала, сегмент записи которого был закрыт, после того, как все данные были прочитаны,чтение возвращает 0(чтение возвращает 0, чтобы указать, что конец файла был прочитан);
    Проверим:


Программа позволяет дочернему процессу записать строку три раза, а затем закрывает дочерний процесс fd [1], то есть закрывает конец записи канала, и не закрывает fd [0] родительского процесса, то есть конец чтения канала.

  1. Если вы пишете в канал, конец чтения которого закрыт, он будетГенерируйте соответствующие сигналыПроцесс записи сегмента завершается. Если сигнал игнорируется или сигнал захватывается и возвращается обработчиком, команда write вернет -1, а errno будет установлено значениеEPIPE;
    Проверим:


Цель кода такова: мы позволяем концу записи (дочернему процессу) всегда записывать строку msg, а конец чтения (родительский процесс) читает три раза, а затем закрывает fd [0] родительского процесса, так что дочерний процесс записывает все время , А родительский процесс не читает. Результаты приведены ниже:

Мы обнаружили, что после того, как родительский процесс закрыл fd [0], дочерний процесс былПрервано ненормально, Из кода выхода и кода сигнала выхода дочернего процесса мы обнаружили, что это сигнал 13 (SIGPIPE) Завершается, поэтому запись в канал, закрытый на конце чтения, не соответствует действительности для PIPE. Операционная система отправит процессу завершения записи после закрытия конца чтенияSIGPIPEВызвать завершение процесса.

  1. Если концы для чтения и записи канала не закрыты, но конец канала для записи больше не записывает данные в канал. В это время, если в конвейере нет данных, процесс чтения будет заблокирован до тех пор, пока в конвейере не появятся данные, прежде чем считывать данные и возвращаться.
  2. Если файловый дескриптор, указывающий на конец чтения канала, не закрыт, а тот, который удерживает конец чтения канала, не читает данные из канала, то есть процесс, записывающий данные в канал. Если канал заполнен, а затем записывает данные в канал, напишите снова Вызывает блокировку процесса до тех пор, пока в канале не останется места, прежде чем он продолжит запись данных в канал и возврат.

емкость трубы

Мы можем пройти* man 7 pipe*; Для запроса пропускной способности трубопроводаpipe_capacity

операционная система Windows предоставляет механизмы для облегчения обмена данными и совместного использования данных между приложениями. В совокупности действия, которые поддерживаются этими механизмами, называются взаимосвязями (IPC). Некоторые формы IPC упрощают разделение труда между несколькими специализированными процессами. Другие формы IPC облегчают разделение труда между компьютерами в сети.

Как правило, приложения могут использовать IPC категории "клиенты" или "серверы". Клиент — это приложение или процесс, запрашивающий службу от какого-либо другого приложения или процесса. Сервер — это приложение или процесс, отвечающий на запрос клиента. Многие приложения действуют как клиент и сервер в зависимости от ситуации. Например, приложение для обработки текстов может выступать в качестве клиента в запросе сводной таблицы производственных затрат из приложения электронной таблицы, выступающего в качестве сервера. Приложение электронной таблицы, в свою очередь, может работать в качестве клиента при запросе последних уровней инвентаризации от приложения управления инвентаризацией.

После принятия решения о том, что приложение будет выгодным из IPC, необходимо решить, какой из доступных методов IPC использовать. Скорее всего, приложение будет использовать несколько механизмов IPC. Ответы на эти вопросы определяют, может ли приложение использовать преимущества одного или нескольких механизмов IPC.

  • Должно ли приложение взаимодействовать с другими приложениями, работающими на других компьютерах в сети, или достаточно для того, чтобы приложение могло обмениваться данными только с приложениями на локальном компьютере?
  • должно ли приложение взаимодействовать с приложениями, работающими на других компьютерах, которые могут работать под управлением разных операционных систем (например, 16-разрядные Windows или UNIX)?
  • Следует ли пользователю приложения выбрать другие приложения, с которыми взаимодействует приложение, или может ли приложение неявным образом найти своих взаимодействующих партнеров?
  • Следует ли, чтобы приложение взаимодействовало со многими различными приложениями обычным образом, например разрешить операции вырезания и вставки с любым другим приложением или должны ли требования к обмену информацией ограничиваться ограниченным набором взаимодействий с конкретными другими приложениями?
  • Является ли производительность критически важным аспектом приложения? Все механизмы IPC включают некоторый объем издержек.
  • Должно ли приложение быть приложением с графическим интерфейсом или консольным приложением? Для некоторых механизмов IPC требуется приложение с графическим пользовательским интерфейсом.

Windows поддерживает следующие механизмы IPC:

Использование буфера обмена для IPC

Буфер обмена выступает в качестве центрального депозита для совместного использования данных между приложениями. Когда пользователь выполняет операцию вырезания или копирования в приложении, приложение помещает выбранные данные в буфер обмена в одном или нескольких стандартных или определенных форматах приложения. Затем любое другое приложение может получить данные из буфера обмена, выбрав из доступных форматов, которые он понимает. Буфер обмена — это очень слабо связанный носитель Exchange, где приложения должны быть согласованы только с форматом данных. Приложения могут находиться на одном компьютере или на разных компьютерах в сети.

Ключевой момент: Все приложения должны поддерживать буфер обмена для тех форматов данных, которые они понимают. Например, текстовый редактор или текстовый процессор должен иметь по крайней мере возможность создавать и принимать данные из буфера обмена в формате чистого текста. Дополнительные сведения см. в разделе буфер обмена.

Использование COM для IPC

Приложения, использующие OLE для управления составными документами, то есть документы, состоящие из данных различных приложений. OLE предоставляет службы, облегчающие приложениям вызов в других приложениях для редактирования данных. Например, текстовый процессор, использующий OLE, может внедрить граф из электронной таблицы. Пользователь может автоматически запустить электронную таблицу с помощью текстового процессора, выбрав внедренную диаграмму для редактирования. OLE берет на себя запуск электронной таблицы и представление графа для редактирования. Когда пользователь закрывает электронную таблицу, диаграмма будет обновлена в исходном документе текстового процессора. Электронная таблица является расширением текстового процессора.

Основой OLE является объектная модель компонента (COM). Программный компонент, использующий COM, может взаимодействовать с множеством других компонентов, даже если они еще не были написаны. Компоненты взаимодействуют как объекты и клиенты. Распределенная модель COM расширяет модели программирования COM таким образом, чтобы она работала по сети.

Ключевой момент: OLE поддерживает составные документы и позволяет приложению включать внедренные или связанные данные, которые при выборе автоматически запускают другое приложение для редактирования данных. Это позволяет расширить приложение с помощью любого другого приложения, использующего OLE. Объекты COM предоставляют доступ к данным объекта через один или несколько наборов связанных функций, известных как интерфейсы. дополнительные сведения см. в разделе COM и ActiveX службы объектов.

Использование копирования данных для IPC

Ключевой момент: копирование данных можно использовать для быстрой отправки сведений в другое приложение с помощью Windows messaging. Дополнительные сведения см. в разделе копирование данных.

Использование DDE для IPC

DDE — это протокол, позволяющий приложениям обмениваться данными в различных форматах. Приложения могут использовать DDE для одноразовых обменов данными или для текущих обменов, в которых приложения обновляются по мере появления новых данных.

Форматы данных, используемые DDE, совпадают с форматами, используемыми в буфере обмена. DDE можно рассматривать как расширение механизма буфера обмена. Буфер обмена почти всегда используется для одноразового ответа на пользовательскую команду, например для выбора команды вставить в меню. DDE также обычно инициируется пользователем с помощью пользовательской команды, но часто остается без вмешательства пользователя. Кроме того, можно определить пользовательские форматы данных DDE для особого целевого IPC между приложениями с более тесно связанными требованиями к обмену данными.

Обмен DDE может происходить между приложениями, запущенными на одном компьютере, или на разных компьютерах в сети.

Ключевой момент: DDE не так эффективнее, как новые технологии. Тем не менее можно по-прежнему использовать DDE, если другие механизмы IPC не подходят или если необходимо взаимодействовать с существующим приложением, которое поддерживает только DDE. дополнительные сведения см. в разделе платформа динамических данных Exchange и платформа динамических данных библиотеки управления Exchange.

Использование сопоставления файлов для IPC

Сопоставление файлов позволяет процессу обрабатывать содержимое файла так, будто он был блоком памяти в адресном пространстве процесса. Процесс может использовать простые операции с указателями для проверки и изменения содержимого файла. Когда двум или более процессам выполняется доступ к одному сопоставлению файлов, каждый процесс получает указатель на память в своем собственном адресном пространстве, который может использоваться для чтения или изменения содержимого файла. Для предотвращения повреждения данных в многозадачной среде процессы должны использовать объект синхронизации, например семафор.

Для предоставления именованной общей памяти между процессами можно использовать особый вариант сопоставления файлов. При указании файла подкачки системы при создании объекта сопоставления файлов объект сопоставления файлов рассматривается как блок общей памяти. Другие процессы могут получить доступ к тому же блоку памяти, открыв тот же объект сопоставления файлов.

Сопоставление файлов является довольно эффективным, а также предоставляет поддерживаемые атрибуты безопасности операционной системы, которые могут помочь предотвратить несанкционированный повреждение данных. Сопоставление файлов может использоваться только между процессами на локальном компьютере. его нельзя использовать по сети.

Ключевой момент: Сопоставление файлов является эффективным способом для двух или более процессов на одном компьютере для совместного использования данных, но необходимо обеспечить синхронизацию между процессами. Дополнительные сведения см. в разделе Сопоставление файлов и Синхронизация.

Использование слота для IPC

Использование каналов для IPC

Существует два типа каналов для двусторонней связи: анонимные каналы и именованные каналы. Анонимные каналы позволяют связанным процессам передавать данные друг другу. Как правило, анонимный канал используется для перенаправления стандартного ввода или вывода дочернего процесса, чтобы он мог обмениваться данными с родительским процессом. Для обмена данными в обоих направлениях (дуплексная операция) необходимо создать два анонимных канала. Родительский процесс записывает данные в один канал, используя его маркер записи, в то время как дочерний процесс считывает данные из этого канала, используя его маркер чтения. Аналогичным образом дочерний процесс записывает данные в другой канал, а родительский процесс считывает из него. Анонимные каналы не могут использоваться по сети и не могут использоваться между несвязанными процессами.

Именованные каналы используются для обмена данными между процессами, которые не являются связанными процессами и между процессами на разных компьютерах. Как правило, серверный процесс именованного канала создает именованный канал с известным именем или именем, которое должно обмениваться с клиентами. Клиентский процесс именованного канала, который знает имя канала, может открыть его другой конец с учетом ограничений доступа, заданных процессом сервера именованных каналов. После того как сервер и клиент подключены к каналу, они могут обмениваться данными, выполняя операции чтения и записи в канале.

Ключевой момент: Анонимные каналы предоставляют эффективный способ перенаправлять стандартные входные или выходные данные в дочерние процессы на том же компьютере. Именованные каналы предоставляют простой программный интерфейс для передачи данных между двумя процессами независимо от того, находятся ли они на одном компьютере или по сети. Дополнительные сведения см. в разделе каналы.

Использование RPC для IPC

RPC позволяет приложениям вызывать функции удаленно. Таким образом, RPC делает IPC проще, чем вызов функции. RPC работает между процессами на одном компьютере или на разных компьютерах в сети.

RPC, предоставляемый Windows, соответствует требованиям к распределенным вычислительным средам (использование) Open Software Foundation (DCE). Это означает, что приложения, использующие RPC, могут взаимодействовать с приложениями, работающими с другими операционными системами, поддерживающими DCE. RPC автоматически поддерживает преобразование данных для учета различных архитектур оборудования и для упорядочения байтов между разнородными средами.

Клиенты и серверы RPC тесно связаны, но по-прежнему поддерживают высокую производительность. Система активно использует RPC для упрощения связи между клиентом и сервером между различными частями операционной системы.

Ключевой момент: RPC — это интерфейс уровня функции с поддержкой автоматического преобразования данных и взаимодействия с другими операционными системами. С помощью RPC можно создавать высокопроизводительные распределенные приложения с высоким уровнем производительности. Дополнительные сведения см. в разделе компоненты Microsoft RPC.

использование сокетов Windows для IPC

Windows Сокеты — это независимый от протокола интерфейс. В нем используются возможности связи базовых протоколов. в сокетах Windows 2 при необходимости можно использовать обработчик сокетов в качестве файла с стандартными функциями файлового ввода-вывода.

Windows Сокеты основаны на гнездах, которые впервые популярны по Berkeley Software Distribution (BSD). приложение, которое использует сокеты Windows, может взаимодействовать с другой реализацией сокета в других типах систем. Однако не все поставщики транспортных служб поддерживают все доступные варианты.

ключевой момент: Windows сокеты — это независимый от протокола интерфейс, поддерживающий текущие и новые сетевые возможности. дополнительные сведения см. в разделе сокеты Windows 2.

Отступление: данная статья является учебной и расчитана на людей, только еще вступающих на путь системного программирования. Ее главный замысел — познакомиться с различными способами взаимодействия между процессами на POSIX-совместимой ОС.

Именованный канал

Примечание: mode используется в сочетании с текущим значением umask следующим образом: (mode &

umask). Результатом этой операции и будет новое значение umask для создаваемого нами файла. По этой причине мы используем 0777 (S_IRWXO | S_IRWXG | S_IRWXU), чтобы не затирать ни один бит текущей маски.

Как только файл создан, любой процесс может открыть этот файл для чтения или записи также, как открывает обычный файл. Однако, для корректного использования файла, необходимо открыть его одновременно двумя процессами/потоками, одним для получение данных (чтение файла), другим на передачу (запись в файл).

В случае успешного создания FIFO файла, mkfifo() возвращает 0 (нуль). В случае каких либо ошибок, функция возвращает -1 и выставляет код ошибки в переменную errno.

  • EACCES — нет прав на запуск (execute) в одной из директорий в пути pathname
  • EEXIST — файл pathname уже существует, даже если файл — символическая ссылка
  • ENOENT — не существует какой-либо директории, упомянутой в pathname, либо является битой ссылкой
  • ENOSPC — нет места для создания нового файла
  • ENOTDIR — одна из директорий, упомянутых в pathname, на самом деле не является таковой
  • EROFS — попытка создать FIFO файл на файловой системе «только-на-чтение»

Пример

mkfifo.c

Мы открываем файл только для чтения (O_RDONLY). И могли бы использовать O_NONBLOCK модификатор, предназначенный специально для FIFO файлов, чтобы не ждать когда с другой стороны файл откроют для записи. Но в приведенном коде такой способ неудобен.

Компилируем программу, затем запускаем ее:

В соседнем терминальном окне выполняем:

В результате мы увидим следующий вывод от программы:

Разделяемая память


Следующий тип межпроцессного взаимодействия — разделяемая память (shared memory). Схематично изобразим ее как некую именованную область в памяти, к которой обращаются одновременно два процесса:

Для выделения разделяемой памяти будем использовать POSIX функцию shm_open():

Функция возвращает файловый дескриптор, который связан с объектом памяти. Этот дескриптор в дальнейшем можно использовать другими функциями (к примеру, mmap() или mprotect()).

Целостность объекта памяти сохраняется, включая все данные связанные с ним, до тех пор пока объект не отсоединен/удален (shm_unlink()). Это означает, что любой процесс может получить доступ к нашему объекту памяти (если он знает его имя) до тех пор, пока явно в одном из процессов мы не вызовем shm_unlink().

  • O_RDONLY — открыть только с правами на чтение
  • O_RDWR — открыть с правами на чтение и запись
  • O_CREAT — если объект уже существует, то от флага никакого эффекта. Иначе, объект создается и для него выставляются права доступа в соответствии с mode.
  • O_EXCL — установка этого флага в сочетании с O_CREATE приведет к возврату функцией shm_open ошибки, если сегмент общей памяти уже существует.

После создания общего объекта памяти, мы задаем размер разделяемой памяти вызовом ftruncate(). На входе у функции файловый дескриптор нашего объекта и необходимый нам размер.

Пример

Следующий код демонстрирует создание, изменение и удаление разделяемой памяти. Так же показывается как после создания разделяемой памяти, программа выходит, но при следующем же запуске мы можем получить к ней доступ, пока не выполнен shm_unlink().

shm_open.c

После создания объекта памяти мы установили нужный нам размер shared memory вызовом ftruncate(). Затем мы получили доступ к разделяемой памяти при помощи mmap(). (Вообще говоря, даже с помощью самого вызова mmap() можно создать разделяемую память. Но отличие вызова shm_open() в том, что память будет оставаться выделенной до момента удаления или перезагрузки компьютера.)

Компилировать код на этот раз нужно с опцией -lrt:

Смотрим что получилось:

Аргумент «create» в нашей программе мы используем как для создания разделенной памяти, так и для изменения ее содержимого.

Зная имя объекта памяти, мы можем менять содержимое разделяемой памяти. Но стоит нам вызвать shm_unlink(), как память перестает быть нам доступна и shm_open() без параметра O_CREATE возвращает ошибку «No such file or directory».

Семафор

Семафор — самый часто употребляемый метод для синхронизации потоков и для контролирования одновременного доступа множеством потоков/процессов к общей памяти (к примеру, глобальной переменной). Взаимодействие между процессами в случае с семафорами заключается в том, что процессы работают с одним и тем же набором данных и корректируют свое поведение в зависимости от этих данных.

  1. семафор со счетчиком (counting semaphore), определяющий лимит ресурсов для процессов, получающих доступ к ним
  2. бинарный семафор (binary semaphore), имеющий два состояния «0» или «1» (чаще: «занят» или «не занят»)

Семафор со счетчиком

Смысл семафора со счетчиком в том, чтобы дать доступ к какому-то ресурсу только определенному количеству процессов. Остальные будут ждать в очереди, когда ресурс освободится.

Итак, для реализации семафоров будем использовать POSIX функцию sem_open():

В функцию для создания семафора мы передаем имя семафора, построенное по определенным правилам и управляющие флаги. Таким образом у нас получится именованный семафор.
Имя семафора строится следующим образом: в начале идет символ "/" (косая черта), а следом латинские символы. Символ «косая черта» при этом больше не должен применяться. Длина имени семафора может быть вплоть до 251 знака.

Если нам необходимо создать семафор, то передается управляющий флаг O_CREATE. Чтобы начать использовать уже существующий семафор, то oflag равняется нулю. Если вместе с флагом O_CREATE передать флаг O_EXCL, то функция sem_open() вернет ошибку, в случае если семафор с указанным именем уже существует.

Параметр mode задает права доступа таким же образом, как это объяснено в предыдущих главах. А переменной value инициализируется начальное значение семафора. Оба параметра mode и value игнорируются в случае, когда семафор с указанным именем уже существует, а sem_open() вызван вместе с флагом O_CREATE.

Для быстрого открытия существующего семафора используем конструкцию:
, где указываются только имя семафора и управляющий флаг.

Пример семафора со счетчиком

Рассмотрим пример использования семафора для синхронизации процессов. В нашем примере один процесс увеличивает значение семафора и ждет, когда второй сбросит его, чтобы продолжить дальнейшее выполнение.

sem_open.c

В одной консоли запускаем:

В соседней консоли запускаем:

Бинарный семафор

Вместо бинарного семафора, для которого так же используется функция sem_open, я рассмотрю гораздо чаще употребляемый семафор, называемый «мьютекс» (mutex).

Мьютекс по существу является тем же самым, чем является бинарный семафор (т.е. семафор с двумя состояниями: «занят» и «не занят»). Но термин «mutex» чаще используется чтобы описать схему, которая предохраняет два процесса от одновременного использования общих данных/переменных. В то время как термин «бинарный семафор» чаще употребляется для описания конструкции, которая ограничивает доступ к одному ресурсу. То есть бинарный семафор используют там, где один процесс «занимает» семафор, а другой его «освобождает». В то время как мьютекс освобождается тем же процессом/потоком, который занял его.

Без мьютекса не обойтись в написании, к примеру базы данных, к которой доступ могут иметь множество клиентов.

Для использования мьютекса необходимо вызвать функцию pthread_mutex_init():

Функция инициализирует мьютекс (перемнную mutex) аттрибутом mutexattr. Если mutexattr равен NULL, то мьютекс инициализируется значением по умолчанию. В случае успешного выполнения функции (код возрата 0), мьютекс считается инициализированным и «свободным».

  • EAGAIN — недостаточно необходимых ресурсов (кроме памяти) для инициализации мьютекса
  • ENOMEM — недостаточно памяти
  • EPERM — нет прав для выполнения операции
  • EBUSY — попытка инициализировать мьютекс, который уже был инициализирован, но не унечтожен
  • EINVAL — значение mutexattr не валидно

Функция pthread_mutex_lock(), если mutex еще не занят, то занимает его, становится его обладателем и сразу же выходит. Если мьютекс занят, то блокирует дальнейшее выполнение процесса и ждет освобождения мьютекса.
Функция pthread_mutex_trylock() идентична по поведению функции pthread_mutex_lock(), с одним исключением — она не блокирует процесс, если mutex занят, а возвращает EBUSY код.
Фунция pthread_mutex_unlock() освобождает занятый мьютекс.

  • EINVAL — mutex неправильно инициализирован
  • EDEADLK — мьютекс уже занят текущим процессом
  • EBUSY — мьютекс уже занят
  • EINVAL — мьютекс неправильно инициализирован
  • EINVAL — мьютекс неправильно инициализирован
  • EPERM — вызывающий процесс не является обладателем мьютекса

Пример mutex

mutex.c

Данный пример демонстрирует совместный доступ двух потоков к общей переменной. Один поток (первый поток) в автоматическом режиме постоянно увеличивает переменную counter на единицу, при этом занимая эту переменную на целую секунду. Этот первый поток дает второму доступ к переменной count только на 10 миллисекунд, затем снова занимает ее на секунду. Во втором потоке предлагается ввести новое значение для переменной с терминала.

Если бы мы не использовали технологию «мьютекс», то какое значение было бы в глобальной переменной, при одновременном доступе двух потоков, нам не известно. Так же во время запуска становится очевидна разница между pthread_mutex_lock() и pthread_mutex_trylock().

Компилировать код нужно с дополнительным параметром -lpthread:

Запускаем и меняем значение переменной просто вводя новое значение в терминальном окне:

Вместо заключения

В следующих статьях я хочу рассмотреть технологии d-bus и RPC. Если есть интерес, дайте знать.
Спасибо.

UPD: Обновил 3-ю главу про семафоры. Добавил подглаву про мьютекс.

• Под обменом данными между параллельными
процессами понимается пересылка данных от
одного потока к другому потоку, предполагая, что эти
потоки выполняются в контексте разных процессов.
• Поток, который посылает данные другому потоку,
называется отправителем.
• Поток, который получает данные от другого потока,
называется адресатом или получателем.

4. Обмен данными между потоками одного процесса

• Если потоки выполняются в контексте
одного процесса, то обмен данными
между ними можно организовать,
используя глобальные переменные и
средства синхронизации потоков.

5. Обмен данными между потоками разных процессов

• Если потоки выполняются в контекстах
разных процессах, то потоки не могут
обращаться к общим переменным.
• В этом случае для обмена данными между
процессами создается канал передачи
данных, который является объектом ядра
операционной системы и представляет собой
область памяти, разделяемую несколькими
процессами и используемую ими для обмена
данными.

6. Схема канала передачи данных

канал передачи данных
T1
B1
K1
M
K2
B2
T1, T2 – потоки пользователя
B1, B2 – буферы ввода-вывода
K1, K2 – потоки ядра операционной системы
M – общая память
T2

7. Порядок работы канала передачи данных


Пересылка данных из потока T1 в поток T2
происходит следующим образом:
1.
2.
3.
4.
Пользовательский поток T1 записывает данные в буфер
B1, используя специальную функцию ядра операционной
системы;
Поток K1 ядра операционной системы читает данные из
буфера B1 и записывает их в общую память M;
Поток K2 ядра операционной системы читает данные из
общей памяти M и записывает их в буфер B2;
Пользовательский поток T2 читает данные из буфера B2.

8. Реализация канала

• Обычно канал реализуется как
кольцевой буфер, работающий по
принципу FIFO.
• Для работы с каналом могут
использоваться такие же функции
ввода-вывода, как и для работы с
файлами.

9. Способы передачи данных по каналам

10. 8.2. Связи между процессами

• Прежде чем пересылать данные между
процессами, нужно установить между
этими процессами связь.
• Связь между процессами
устанавливается как на физическом
(аппаратном), так и логическом
(программном) уровнях.

11. Направления передачи данных

• С точки зрения направления передачи
данных различают следующие виды
связей:
– полудуплексная связь – данные по этой
связи могут передаваться только в одном
направлении;
– дуплексная связь – данные по этой связи
могут передаваться в обоих направлениях.

12. Топологии связей

• Теперь, предполагая, что
рассматриваются только
полудуплексные связи, определим
возможные топологии связей.
• Под топологией связи будем
понимать конфигурацию связей между
процессами отправителями и
получателями.

13. Виды связей

• С точки зрения топологии различают
следующие виды связей:
1 1 - между собой связаны только два
процесса;
1 N - один процесс связан с N процессами;
N 1 - каждый из N процессов связан с одним
процессом;
N M - каждый из N процессов связан с каждым
из M процессов.

14. Обозначения

15. Топология связей между процессами

16. Порты и почтовые ящики

• Канал передачи данных, реализующий
топологию N 1 обычно называется
портом.
• Канал передачи данных, реализующий
топологию N M обычно называется
почтовым ящиком.

17. Порядок разработки систем обмена данными

1. При разработке систем с обменом данными
между процессами, прежде всего, должна
быть выбрана топология связей и
направления передачи данных по этим
связям.
2. После этого в программах реализуются
выбранные связи между процессами,
используя функции операционной системы,
предназначенные для установки связи
между процессами.

18. Функции для установки связей между процессами

• Для установки связей между процессами
обычно используются функции типа:
– connect – установить связь;
– disconnect – разорвать связь.
• Эти функции, а также функции для обмена
данными между процессами обеспечивает
система передачи данных, которая обычно
является частью ядра операционной
системы.

21. Типы адресации процессов

22. Прямая адресация процессов

23. Косвенная адресация процессов

24. Симметричная и асимметричная адресация

25. Адресация в системах клиент-сервер

26. Протокол

• Набор правил, по которым
устанавливаются связи и передаются
данные между процессами, называется
протоколом.

27. 8.4. Синхронный и асинхронный обмен данными

• При передаче данных различают
синхронный и асинхронный обмен
данными.

31. Рандеву

32. 8.5. Буферизация

33. Типы буферизации

• Как видно из этих определений типы
буферизации тесно связаны с
синхронизацией передачи данных и
поэтому также должны учитываться при
разработке систем, которые используют
обмен данными между процессами.

35. 8.6. Анонимные каналы в Windows

• Анонимным каналом называется объект
ядра операционной системы, который
обеспечивает передачу данных между
процессами, выполняющимися на одном
компьютере.
• Процесс, который создает анонимный канал,
называется сервером анонимного канала.
• Процессы, которые связываются с
анонимным каналом, называются
клиентами анонимного канала.

36. Свойства анонимных каналов


не имеют имени;
полудуплексные;
передача данных потоком;
синхронный обмен данными;
возможность моделирования любой
топологии связей.

37. Порядок работы с анонимным каналом


создание анонимного канала сервером;
соединение клиентов с каналом;
обмен данными по каналу;
закрытие канала.

38. Соединение клиентов с анонимным каналом

39. Функции для работы с анонимным каналом

• CreatePipe – создание анонимного
канала;
• WriteFile – запись данных в анонимный
канал;
• ReadFile – чтение данных из
анонимного канала;

40. 8.7. Именованные каналы в Windows

• Именованным каналом называется объект
ядра операционной системы, который
обеспечивает передачу данных между
процессами, выполняющимися на
компьютерах в одной локальной сети.
• Процесс, который создает именованный
канал, называется сервером именованного
канала.
• Процессы, которые связываются с
именованным каналом, называются
клиентами именованного канала.

41. Свойства именованных каналов

42. Порядок работы с именованными каналами

• создание именованного канала сервером:
• соединение сервера с экземпляром
именованного канала;
• соединение клиента с экземпляром
именованного канала;
• обмен данными по именованному каналу;
• отсоединение сервера от экземпляра
именованного канала;
• закрытие именованного канала клиентом и
сервером.

43. Функции для соединения с именованным каналом

• CreateNamedPipe – создание именованного
канала;
• ConnectNamedPipe – соединение сервера с
клиентом именованного канала;
• DisconnectNamedPipe – отсоединение
сервера от именованного канала;
• WaitNamedPipe – ожидание клиентом
свободного экземпляра именованного канала;
• CreateFile – соединение клиента с
именованным каналом;

44. Функции для передачи данных по именованному каналу

45. Функции для работы с состоянием и свойствами именованного канала

• GetNamedPipeHandleState –
определение состояния именованного
канала;
• SetNamedPipeHandleState – изменение
состяния именованного канала;
• GetNamedPipeInfo – получить
информацию об атрибутах
именованного канала;

46. 8.8. Почтовые ящики в Windows

47. Свойства почтовых ящиков

49. Порядок работы с почтовым ящиком

• создание почтового ящика сервером:
• соединение клиента с почтовым
ящиком;
• обмен данными через почтовый ящик;
• закрытие почтового ящика клиентом и
сервером.

50. Функции для работы с почтовыми ящиками

• CreateMailslot – создание почтового ящика;
• CreateFile – соединение клиента с почтовым
ящиком;
• WriteFile – запись данных в почтовый ящик;
• ReadFile – чтение данных из почтового
ящика;
• GetMailslotInfo – получение информации о
свойствах почтового ящика;
• SetMailslotInfo – изменение сервером
времени ожидания от клиента.

Читайте также: