Skip to content

katyasots/shared-memory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shared-memory

Взаимодействие через разделяемую память в Docker

Описание

Проект демонстрирует межпроцессное взаимодействие (IPC) с использованием разделяемой памяти System V в Docker-контейнере. В него входят две программы на C:

  1. writer.c — создаёт сегмент разделяемой памяти, записывает в него "Hello world!" и выводит идентификатор памяти.
  2. reader.c — получает идентификатор памяти из стандартного ввода, считывает из памяти сообщение, выводит его и удаляет сегмент.

Программы запускаются внутри Docker-контейнера, основанного на образе gcc:11.3.0.

Структура репозитория

.
├── src/             # Исходные файлы программ
│   ├── writer.c     # Запись данных в разделяемую память
│   ├── reader.c     # Чтение данных из разделяемой памяти
├── Dockerfile      # Настройка Docker-образа
├── build.sh        # Скрипт сборки Docker-образа
├── run.sh          # Скрипт запуска программ
└── README.md       # Документация

Требования

  • Docker установлен на вашей системе

Установка и использование

1. Сборка Docker-образа

Запустите build.sh, чтобы скомпилировать программы и создать образ Docker:

./build.sh

Прим. Docker может требовать root-доступ, в таком случае необходимо собрать образ с помощью команды:

sudo ./build.sh

После выполнения создастся образ с именем shm-example.

2. Запуск программ

Выполните run.sh, чтобы запустить программы:

./run.sh

Прим. Docker может требовать root-доступ, в таком случае необходимо запустить программы с помощью команды:

sudo ./run.sh

Скрипт выполняет:

  1. Запуск контейнера с флагом --ipc=host для того, чтобы контейнер мог использовать общую память хоста.
  2. Запуск программы writer, которая создает сегмент разделяемой памяти и выводит её идентификатор в стандартный вывод.
  3. Запуск программы reader, которая получает идентификатор памяти через стандартный ввод, считывает из сегмента памяти сообщение и выводит его.

Как это работает

  1. Процесс записи (writer.c):

    • shmget() создает новый сегмент разделяемой памяти.
      Аргументы:

      • key_t key — уникальный ключ для сегмента разделяемой памяти (в данном случае используется IPC_PRIVATE, чтобы создать новый сегмент).
      • size_t size — размер сегмента разделяемой памяти (в данном случае 1000, что соответствует размеру строки).
      • int shmflg — флаги для создания сегмента. Мы используем IPC_CREAT | 0666, что создаёт сегмент с правами на чтение и запись для всех пользователей.

      Возвращаемое значение: идентификатор сегмента памяти или -1 в случае ошибки.

    • shmat() подключает процесс к сегменту разделяемой памяти.
      Аргументы:

      • int shmid — идентификатор сегмента, полученный из shmget().
      • const void *shmaddr — адрес, по которому процесс должен подключить сегмент памяти. В данном случае передается NULL, и система сама выбирает подходящий адрес.
      • int shmflg — флаги подключения. Передается 0, что означает стандартный режим.

      Возвращаемое значение: указатель на начало сегмента памяти или -1 в случае ошибки.

    • strncpy() копирует строку "Hello world!" в память, ограничив её длину до заданного значения (в данном случае SHM_SIZE, равное 1000).

    • Программа выводит идентификатор сегмента разделяемой памяти с помощью printf(). Этот идентификатор будет передан в программу чтения через аргумент командной строки.

    • shmdt() отключает процесс от сегмента разделяемой памяти.
      Аргументы:

      • const void *shmaddr — указатель на сегмент памяти, от которого нужно отключиться.

      Возвращаемое значение: 0 в случае успешного отключения, -1 в случае ошибки.

  2. Процесс чтения (reader.c):

    • Программа считывает ключ разделяемой памяти из стандартного ввода, используя scanf().

    • shmat() подключает процесс к сегменту разделяемой памяти (была описана выше).

    • printf() выводит данные из разделяемой памяти на экран.

    • shmdt() отключает процесс от сегмента разделяемой памяти (описана выше).

    • shmctl() управляет сегментами разделяемой памяти.
      Аргументы:

      • int shmid — идентификатор сегмента, который нужно удалить.
      • int cmd — команда управления. В данном случае используется IPC_RMID, чтобы удалить сегмент.
      • struct shmid_ds *buf — структура для получения информации о сегменте. В данном случае передается NULL.

      Возвращаемое значение: 0 в случае успеха, -1 в случае ошибки.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published