Interprocess CommunicationРефераты >> Программирование и компьютеры >> Interprocess Communication
Третья функция - открепление разделяемой памяти:
int shmdt(char *shmaddr);
shmaddr - адрес прикрепленной к процессу памяти, который был получен при подключении памяти в начале работы.
Четвертая функция - управление разделяемой памятью:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid - идентификатор разделяемой памяти
cmd - команда управления.
В частности, могут быть команды: IPC_SET (сменить права доступа и владельца ресурса - для этого надо иметь идентификатор автора данного ресурса или суперпользователя), IPC_STAT (запросить состояние ресурса - в этом случае заполняется информация в структуру, указатель на которую передается третьим параметром, IPC_RMID (уничтожение ресурса - после того, как автор создал процесс - с ним работают процессы, которые подключаются и отключаются, но не уничтожают ресурс, а с помощью данной команды мы уничтожаем ресурс в системе).
Это все, что касается функций управления разделяемой памятью.
Передача сообщений.
|
Следующим средством взаимодействия процессов в системе IPC - это передача сообщений. Ее суть в следующем: в системе имеется так называемая очередь сообщений, в которой каждое сообщение представляет из себя структуру данных, с которой ассоциирован буфер, содержащий тело сообщения и признак, который называется типом сообщения. Очередь сообщений может быть рассмотрена двояко:
· очередь рассматривается, как одна единственная сквозная очередь, порядок сообщений в которой определяется хронологией их попадания в эту очередь.
· кроме того, так как каждое сообщение имеет тип (на схеме - буква рядом с номером сообщения), то эту очередь можно рассматривать, как суперпозицию очередей, связанную с сообщениями одного типа.
Система IPC позволяет создавать разделяемый ресурс, называемый “очередь сообщений” - таких очередей может быть произвольное количество. По аналогии с разделяемой памятью - мы можем создать очередь, подключиться к ней, послать сообщение, принять сообщение, уничтожить очередь и т.д. Рассмотрим функции работы с очередями сообщений:
Создание очереди сообщений:
int msgget(key_t key, int flags);
 çàâèñèìîñòè îò ôëàãîâ ïðè îáðàùåíèè ê äàííîé ôóíêöèè ëèáî ñîçäàåòñÿ ðàçäåëÿåìûé ðåñóðñ, ëèáî îñóùåñòâëÿåòñÿ ïîäêëþ÷åíèå ê уже ñóùåñòâóþùåìó.
Отправкасообщения:
int msgsnd( int id, struct msgbuf *buf, int size, int flags);
id - идентификатор очереди сообщения;
struct msgbuf {
long type; /* тип сообщения */
char mtext[s] /* указатель на тело сообщения */
}
size - размер сообщения, здесь указывается размер сообщения, размещенного по указателю buf;
flags - флаги, в частности, флагом может быть константа IPC_NOWAIT. При наличии такого флага будут следующие действия - возможна ситуация, когда буфера, предусмотренные системой под очередь сообщений, переполнены. В этом случае возможны два варианта - процесс будет ожидать освобождения пространства, если не указано IPC_NOWAIT, либо функция вернет -1 (с соответствующим кодом в errno), если было указано IPC_NOWAIT.
Прием сообщения:
int msgrcv( int id, struct msgbuf *buf, int size, long type, int flags);
id - идентификатор очереди;
buf - указатель на буфер, куда будет принято сообщение;
size - размер буфера, в котором будет размещено тело сообщения;
type - если тип равен нулю, то будет принято первое сообщение из сквозной очереди, если тип больше нуля, то в этом случае будет принято первое сообщение из очереди сообщений, связанной с типом, равным значению этого параметра.
flags - флаги, в частности, IPC_NOWAIT, он обеспечит работу запроса без ожидания прихода сообщения, если такого сообщения в момент обращения функции к ресурсу не было, иначе процесс будет ждать.
Управление очередью:
int msgctl( int id, int cmd, struct msgid_dl *buf);
id - идентификатор очереди;
cmd - команда управления, для нас интерес представляет IPC_RMID, которая уничтожит ресурс.
buf - этот параметр будет оставлен без комментария.
Мы описали два средства взаимодействия между процессами. Что же мы увидели? Понятно, что названия и описания интерфейсов мало понятны. Прежде всего следует заметить то, что как только мы переходим к вопросу взаимодействия процессов, у нас возникает проблема синхронизации. И здесь мы уже видим проблемы, связанные с тем, что после того, как мы поработали с разделяемой памятью или очередью сообщений, в системе может оставаться “хлам”, например, процессы, которые ожидают сообщений, которые в свою очередь не были посланы. Так, если мы обратились к функции получения сообщений с типом, которое вообще не пришло, и если не стоит ключ IPC_NOWAIT, то процесс будет ждать его появления, пока не исчезнет ресурс. Или мы можем забыть уничтожить ресурс (и система никого не поправит) - этот ресурс останется в виде загрязняющего элемента системы.
Когда человек начинает работать с подобными средствами, то он берет на себя ответственность за все последствия, которые могут возникнуть. Это первый набор проблем - системная синхронизация и аккуратность. Вторая проблема - синхронизация данных, когда приемник и передатчик работают синхронно. Заметим, что самый плохой по синхронизации ресурс из рассмотренных нами - разделяемая память. Это означает, что корректная работа с разделяемой памятью не может осуществляться без использования средств синхронизации, и, в частности, некоторым элементом синхронизации может быть очередь сообщений. Например, мы можем записать в память данные и послать сообщение приемнику, что информация поступила в ресурс, после чего приемник, получив сообщение, начинает считывать данные. Также в качестве синхронизирующего средства могут применяться сигналы.
И это главное - не язык интерфейсов, а проблемы, которые могут возникнуть при взаимодействии параллельных процессов.
Лекция №18
К сегодняшнему дню мы разобрали два механизма взаимодействия процессов в системе IPC - это механизм общей (или разделяемой) памяти и механизм сообщений. Мы с вами выяснили, что одной из основных проблем, возникающей при взаимодействии процессов, является проблема синхронизации. Ярким примером механизма, для которого эта проблема является наиболее острой, является механизм взаимодействия процессов с использованием разделяемой памяти.