Самодел 2003 (1114718), страница 13

Файл №1114718 Самодел 2003 (Старые версии Машбука или нечто подобное) 13 страницаСамодел 2003 (1114718) страница 132019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 13)

Как сгенерировать такой уникальный ключ?

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

Для решения этой задачи служит функция ftok():

#include <sys/types.h>

#include<sys/ipc.h>

key_t ftok (char *filename, char proj)

где filename –имя существующего в ФС файла и его атрибутыж

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

Эта функция генерирует значение ключа по некоторой строке символов и добавочному символу (букве), передаваемым в качестве параметров. Гарантируется, что полученное таким образом значение будет отличаться от всех других значений, сгенерированных функцией ftok() с другими значениями параметров, и в то же время, при повторном запуске ftok() с теми же параметрами, будет получено то же самое значение ключа. Если же файл удалить из ФС, а затем создать новый с тем же именем, вызвать ftok() с тем же параметром, то гарантированно создастся другое имя, т.к. например, учитывается файловый дескриптор.

Следует заметить, что функция ftok() не является системным вызовом, а предоставляется библиотекой.

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

Ели указано значение IPC_PRIVATE, создается ресурс, который будет доступен только породившему его процессу. Такие ресурсы обычно порождаются родительским процессом, который затем сохраняет полученный дескриптор в некоторой переменной и порождает своих потомков. Т.к. потомкам доступен уже готовый дескриптор созданного объекта, они могут непосредственно работать с ним, не обращаясь предварительно к «get»-методу. Таким образом, созданный ресурс может совместно использоваться родительским и порожденными процессами. Однако если один из этих процессов повторно вызовет «get»-метод с ключом IPC_PRIVATE, в результате будет получен другой, совершенно новый разделяемый ресурс, т.к. при обращении к «get»-методу с ключом IPC_PRIVATE всякий раз создается новый объект нужного типа.

Если при обращении к «get»-методу указан ключ, отличный от IPC_PRIVATE, происходит следующее:

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

 Если объект с заданным ключом не найден, и среди переданных флагов отсутствует флаг IPC_CREAT, «get»-метод вернет –1, а в переменной errno будет установлено значение ENOENT

 Если объект с заданным ключом найден среди существующих, «get»-метод вернет дескриптор для этого существующего объекта, т.е. фактически, в этом случае происходит подключение к уже существующему объекту по заданному ключу. Если процесс ожидал создания нового объекта по указанному ключу, то для него такое поведение может оказаться нежелательным, т.к. это будет означать, что в результате случайного совпадения ключей (например, если процесс не использовал функцию ftok()) он подключился к чужому ресурсу. Чтобы избежать такой ситуации, следует указать в параметре флагов наряду с флагом IPC_CREAT и правами доступа еще и флаг IPC_EXCL – в этом случае «get»-метод вернет -1, если объект с таким ключом уже существует (переменная errno будет установлена в значение EEXIST)

 Следует отметить, что при подключении к уже существующему объекту дополнительно проверяются права доступа к нему. В случае, если процесс, запросивший доступ к объекту, не имеет на то прав, «get»-метод вернет –1, а в переменной errno будет установлено значение EACCESS

Нужно заметить, что для каждого типа объектов IPC существует некое ограничение на максимально возможное количество одновременно существующих в системе объектов данного типа. Если при попытке создания нового объекта окажется, что указанное ограничение превышено, «get»-метод, совершавший попытку создания объекта, вернет -1, а в переменной errno будет указано значение ENOSPC.

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

Очередь сообщений – организованная совокупность типизированных сообщений, организованное по принципу FIFO. Имеет 2 поля:

  • тип сообщеня;

  • тело сообщения представляющий собой некоторое целое число.

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

либо как некоторая совокупность подочередей, каждая из которых

содержит элементы определенного типа


. Извлечение сообщений из очереди происходит согласно принципу FIFO – в порядке их записи, однако процесс-получатель может указать, из какой подочереди он хочет извлечь сообщение, или, иначе говоря, сообщение какого типа он желает получить – в этом случае из очереди будет извлечено самое «старое» сообщение нужного типа.

Рассмотрим набор системных вызовов, поддерживающий работу с очередями сообщений.

1) Доступ к очереди сообщений.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/message.h>

int msgget (key_t key, int msgflag)

где key – ключ

msgflag – флаги, управляющие поведением вызова

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

2)

Отправка сообщения.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)

где msqid – идентификатор очереди, полученный в результате вызова msgget()

msgp – указатель на буфер следующей структуры:

long msgtype -тип сообщения

char msgtext[ ] -данные (тело сообщения)

msgsz - предельный размер сообщения (буфера).

В заголовочном файле <sys/msg.h> определена константа MSGMAX, описывающая максимальный размер тела сообщения. При попытке отправить сообщение, у которого число элементов в массиве msgtext превышает это значение, системный вызов вернет –1.

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

В случае удачной записи возвращаемое значение вызова равно 0.

3)

Получение сообщения.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)

где -

Первые три аргумента аналогичны аргументам предыдущего вызова

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

msgflg - комбинация (побитовое сложение) флагов. Если среди флагов не указан IPC_NOWAIT, и в очереди не найдено ни одного сообщения, удовлетворяющего критериям выбора, процесс будет заблокирован до появления такого сообщения. (Однако, если такое сообщение существует, но его длина превышает указанную в аргументе msgsz, то процесс заблокирован не будет, и вызов сразу вернет –1. Сообщение при этом останется в очереди). Если же флаг IPC_NOWAIT указан, то вызов сразу вернет –1.

Процесс может также указать флаг MSG_NOERROR – в этом случае он может прочитать сообщение, даже если его длина превышает указанную емкость буфера. В этом случае в буфер будет записано первые msgsz байт из тела сообщения, а остальные данные отбрасываются.

В случае удачного чтения возвращаемое значение вызова равно 0.

4)

Управление очередью сообщений.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgctl (int msqid, int cmd, struct msgid_ds *buf)

где msqid -

идентификатор ресурса,

cmd - команда, которую необходимо выполнить. Возможные значения:

IPC_STAT – скопировать структуру, описывающую управляющие параметры очереди по адресу, указанному в параметре buf

IPC_SET – заменить структуру, описывающую управляющие параметры очереди, на структуру, находящуюся по адресу, указанному в параметре buf

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

*buf - структура, описывающая управляющие параметры очереди. Тип msgid_ds описан в заголовочном файле <sys/message.h>, и представляет собой структуру, в полях которой хранятся права доступа к очереди, статистика обращений к очереди, ее размер и т.п.

Данный вызов используется для получения или изменения процессом управляющих параметров, связанных с очередью и уничтожения очереди.

Рассмотрим пример.

Напишем программу: первый процесс будет читать некоторую текстовую строку из стандартного ввода и в случае, если строка начинается с буквы 'a', то эта строка в качестве сообщения будет передана процессу А, если 'b' - процессу В, если 'q' - то процессам А и В и затем будет осуществлен выход. Процессы А и В распечатывают полученные строки на стандартный вывод.

Основной процесс

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/message.h>

#include <stdio.h>

struct {long mtype; // тип сообщения

char Data[256]; // сообщение

} Message;

int main()

{

key_t key; int msgid; char str[256];

key=ftok("/usr/mash",'s');

// получаем ключ, однозначно определяющий доступ к ресурсу данного типа

msgid=msgget(key, 0666 | IPC_CREAT);

// создаем очередь сообщений , 0666 определяет права доступа

for(;;)

{ //запускаем вечный цикл

gets(str); // читаем из стандартного ввода строку

strcpy(Message.Data, str); // и копируем ее в буфер сообщения

switch(str[0])

{

case 'a':

case 'A': Message.mtype=1;//устанавливаем тип, посылаем сообщение в очередь

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str)+1, 0);

break;

case 'b':

case 'B': Message.mtype=2;

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str)+1, 0);

break;

case q':

case 'Q': Message.mtype=1;

msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str)+1, 0);

Message.mtype=2;

Характеристики

Тип файла
Документ
Размер
2,4 Mb
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6353
Авторов
на СтудИзбе
311
Средний доход
с одного платного файла
Обучение Подробнее