Реферат: 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);