/
Text
Лабораторная работа №
6
Взаимодействие и обмен
данны
ми
между процессами
(4
ч.)
Средства
IPC
в
Linux
.
Разделяемая память, именованные каналы
FIFO
.
Задание
1.
На основе механизма разделяемой памяти
Linux
разработайте
приложение, выполняющее обмен строками пр
оизвольной длины между
двумя программами.
Задание
2.
Разработайте приложение
на основе
FIFO
, позволяющее
обмениваться текстовыми сообщениями между двумя копиями этого
приложения, запущенными в разных консолях одной операционной системы.
Дополнительная ин
формация
В
Linux
для передачи данных между процессами могут использоваться
различные средства
IPC
:
сигналы,
сокеты, очереди сообщений, совместно
используемая память, неименованные каналы (
pipes
),
FIFO
, чтение, запись и
блокировка временных файлов.
Для нек
оторых средств (например, разделяемая память, очереди
сообщений) существует несколько реализации: считающаяся морально
устаревшей реализация
System
V
и более современная
–
стандарта
POSIX
.
При использовании механизмов IPC следует учитывать их преимущества
и ограничения:
разделяемая память
является самым быстрым способом
взаимодействия, но вы должны самостоятельно предусмотреть
синхронизацию работающих с нею процессов;
неименованные каналы
могут
использоваться только между родственными процессами;
каналы
,
ра
зделяемая память
и
очереди сообщений
доступны только на локальной
системе;
сокеты
используются как при организации локального
взаимодействия (семейство
AF
_
UNIX
), так и для взаимодействия по сети. В
настоящее время,
сокеты
являются доминирующим средством IP
C.
Средства, подобные
почтовым ящикам Windows
в UNIX и Linux
отсутствуют
.
Именованные каналы
FIFO
(именованные каналы) аналогичны именованным каналам
Windows
. Они обеспечивают взаимодействие не связанных между собой
процессов. Однако по сравнению с именова
нными каналами
Windows
их
возможности являются несколько ограниченными:
Каналы
FIFO
являются полудуплексными;
Каналы
FIFO
действуют только в пределах локального компьютера;
Каналы
FIFO
о
риентированы на работу с байтовым потоком
, поэтому в
клиент
-
серверных
приложениях
требуется использовать один из
способов разделения полученного потока на отдельные сообщения.
П
роще всего использовать записи фиксир
о
ванной длины. Тем не
менее, отдельные операции чтения и записи я
в
ляются атомарными.
Файл
FIFO
представляет соб
ой канал, который представлен
специальным именованным файлом в файловой сист
е
ме. Любой процесс
может открыть или закрыть такой файл. В отличие от н
е
именованных
каналов (
pipes
), процессы, использующие именованный канал (
FIFO
), не
обязаны быть связанными друг с другом.
Именованный канал может быть создан несколькими способами:
1
)
С помощью утилиты
mkfifo
.
2
)
Системным вызовом.
В качестве иллюстрации
проделайте
следующий
эксперимент
:
войдите в двух консолях (или двух окнах терминал
а) в один и тот же каталог
(например, Ваш домашний) и создайте файл
FIFO
с помощью вызова
mkfifo
.
$ cd ~
$
mkfifo
myfifo
Убедитесь, что файл именованного канала создан с помощью команды
ls
, выводящей список файлов (файл именованного канала будет помечен
бу
квой
p
–
pipe
).
$ ls
–
l
p
rw
-
r
--
r
--
1 user user 0 myfifo
В одной консоли выполните команду
cat
для чтения
данных
со
стандартного ввода
в
FIFO
,
$
cat
>
myfifo
или команду
echo
для записи в
FIFO
строки:
$
echo
"
Hello
,
world
!" >>
myfifo
в другой консоли
команд
у
cat
для вывода
данных
из
канала
FIFO
на
стандартный вывод:
$
cat
<
myfifo
Попробуйте набрать что
-
нибудь в первой консоли и нажать клавишу
<
Enter
>
(или запишите строку через
echo
)
. Убедитесь, что введенный текст
отображается на второй консоли. Канал закры
вается с помощью комбинации
<
CTRL
+
D
> в первой консоли. Для удаления файла
FIFO
можно использовать
обычную команду удаления файла:
$
rm
myfifo
Для создания именованного канала используется системный вызов
int
mkfifo(
const
char
* path_name, mode_t mode);
з
десь
path
_
name
–
путь к файлу
FIFO
и его имя,
mode
–
права доступа к каналу (подробнее 2 секция мануала для вызова
creat
).
Возвращается 0, если вызов выполнен успешно. Если канал не может
быть создан, функция возвращает
–
1. Для работы с функцией нужно
подк
лючить заголовочные файлы
<
sys
/
types
.
h
>
и
<
sys
/
stat
.
h
>
.
К полученному
FIFO
-
файлу можно обращаться как к обычному файлу.
Одна программа должна открыть его для записи, другая программа для
чтения. Над файлом можно выполнять как низкоуровневые (
open
()
,
write
()
,
read
()
,
close
()
и др.), так и высокоуровневые (
fopen
()
,
fprintf
()
,
fscanf
()
,
fclose
()
и др.) функции.
Например, запись в
FIFO
-
канал на низком уровне:
int
fd = open (fifo_path, O_WRONLY);
write (fd, data, data_length);
close
(
fd
);
чтение на высоком уров
не:
FILE * fifo = fopen (fifo_path, “r”);
fscanf (fifo, “%s”, buffer);
fclose
(
fifo
);
После окончания использования именованный канал может быть
удален как обычный файл:
unlink
(
fifo
_
name
);
У
FIFO
-
канала может быть несколько записывающих программ.
Серве
р, на котором применяется это средство, должен использовать
для ка
ж
дого ответа клиентам отдельный канал FIFO, хотя все клиенты могут
пос
ы
лать запросы по одному и тому же известному каналу. В соответствии с
о
б
щепринятой практикой клиенты включают имя канала
FIFO в запрос
соед
и
нения.