Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Memory attached at 40017000

$ ./shm2

Memory attached at 40017000

Enter some text: hello

You wrote: hello

waiting for client...

waiting for client...

Enter some text: Linux!

You wrote: Linux!

waiting for client...

waiting for client...

waiting for client...

Enter some text: end

You wrote: end

$

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

Первая программа shm1 создает сегмент совместно используемой памяти и затем присоединяет его к своему адресному пространству. Вы накладываете структуру

shared_use_st
на начальную область совместно используемой памяти. У нее есть флаг
written_by_you
, который устанавливается, когда данные доступны. Если флаг установлен, программа считывает текст, выводит его и сбрасывает флаг, чтобы показать, что данные прочитаны. Для корректного выхода из цикла примените специальную строку
end
. Далее программа отсоединяет сегмент совместно используемой памяти и удаляет его.

Вторая программа shm2 получает и присоединяет тот же самый сегмент совместно используемой памяти, поскольку она применяет тот же ключ 1234. Затем она просит пользователя ввести текст. Если флаг

written_by_you
установлен, shm2 знает, что клиентский процесс еще не считал предыдущую порцию данных и ждет завершения чтения. Когда другой процесс очищает флаг, shm2 записывает новые данные и устанавливает флаг. Она также пользуется магической строкой
end
для завершения записи и отсоединения сегмента совместно используемой памяти.

Обратите внимание на то, что вы вынуждены с помощью флага

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

Очереди сообщений

Теперь рассмотрим третье и последнее средство System V IPC: очереди сообщений. Во многом очереди сообщений похожи на именованные каналы, но без сложностей, сопровождающих открытие и закрытие канала. Однако применение очереди сообщений не избавляет вас от проблем, возникающих при использовании именованных каналов, например блокировки заполненных каналов.

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

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

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

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

Далее приведены объявления функций для работы с очередями сообщений:

#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

int msgget(key_t key, int msgflg);

int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);

Как и в случае семафоров или совместно используемой памяти, заголовочные файлы sys/types.h и sys/ipc.h обычно автоматически включаются заголовочным файлом msg.h.

msgget

Очередь сообщений создается и предоставляет к себе доступ с помощью функции

msgget
:

int msgget(key_t key, int msgflg);

Программа должна предоставить значение параметра

key
, которое, как и в других средствах IPC, задает имя конкретной очереди сообщений. С помощью специального значения
IPC_PRIVATE
создается скрытая или частная очередь, которая теоретически доступна только текущему процессу. Как и в случае семафоров и совместно используемой памяти, в некоторых системах Linux такая очередь может не быть частной. Поскольку от скрытой или частной очереди очень мало пользы, это не слишком важная проблема. Как и раньше, второй параметр
msgflg
состоит из девяти флагов прав доступа. Для создания новой очереди сообщений специальный бит со значением
IPC_CREAT
должен быть объединен с правами доступа поразрядной операцией
OR
. Не считается ошибкой установка флага
IPC_CREAT
и задание ключа уже существующей очереди сообщений. Если очередь уже есть, флаг
IPC_CREAT
безмолвно игнорируется.

Функция

msgget
вернет положительное число, идентификатор очереди; в случае успешного завершения и -1 в случае сбоя.

msgsnd

Функция

msgsnd
позволяет добавить сообщение в очередь сообщений:

int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);

Структура сообщения ограничена двумя способами. Во-первых, она должна быть меньше системного ограничения, и во-вторых, она должна начинаться с элемента типа

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

Поделиться:
Популярные книги

Ненаглядная жена его светлости

Зика Натаэль
Любовные романы:
любовно-фантастические романы
6.23
рейтинг книги
Ненаглядная жена его светлости

Казачий князь

Трофимов Ерофей
5. Шатун
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Казачий князь

Любимая учительница

Зайцева Мария
1. совершенная любовь
Любовные романы:
современные любовные романы
эро литература
8.73
рейтинг книги
Любимая учительница

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

Двойник короля 11

Скабер Артемий
11. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 11

Барон устанавливает правила

Ренгач Евгений
6. Закон сильного
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Барон устанавливает правила

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5

Идеальный мир для Лекаря 13

Сапфир Олег
13. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 13

Бальмануг. (Не) Любовница 2

Лашина Полина
4. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Бальмануг. (Не) Любовница 2

Я – Легенда 2: геном хищника

Гарцевич Евгений Александрович
2. Я - Легенда!
Фантастика:
боевая фантастика
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Я – Легенда 2: геном хищника

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

Точка Бифуркации IX

Смит Дейлор
9. ТБ
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Точка Бифуркации IX

Последний Паладин. Том 6

Саваровский Роман
6. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 6

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2