Системное программное обеспечение - Учебное пособие (Терехин А.Н.)

4.9      средства межпроцессного взаимодействия system v.

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

Поэтому практически все UNIX-системы поддерживают более мощные и развитые средства межпроцессного взаимодействия, хотя появление и развитие этих средств в разных версиях UNIX шло разными путями.. Рассматриваемую в этой главе группу средств межпроцессного взаимодействия называют System V IPC[11], так как изначально эти средства были реализованы именно в UNIX System V, однако теперь она реализована во всех версиях UNIX. Она включает в себя очереди сообщений, семафоры, разделяемую память.

Следует отметить, что объекты и методы IPC поддерживаются стандартом POSIX (хотя они определены не в самом стандарте POSIX.1, а в стандарте POSIX.1b, описывающем переносимую ОС реального времени), однако, синтаксис их отличается от предложенного в System V, в частности, используется другое пространство имен. Далее в этой главе мы рассмотрим  методы IPC так, как они реализованы в System V.

Организация доступа и именования в разделяемых ресурсах.

Именование разделяемых объектов.

Для всех средств IPC приняты общие правила именования объектов, позволяющие процессу получить доступ к такому объекту. Для именования объекта IPC используется ключ, представляющий собой целое число. Ключи являются уникальными во всей UNIX-системе идентификаторами объектов IPC, и зная ключ для некоторого объекта, процесс может получить к нему доступ. При этом процессу возвращается дескриптор объекта, который в дальнейшем используется для всех операций с ним. Проведя аналогию с файловой системой, можно сказать, что ключ аналогичен имени файла, а получаемый по ключу дескриптор – файловому дескриптору, получаемому во время операции открытия файла. Ключ для каждого объекта IPC задается в момент его создания тем процессом, который его порождает, а все процессы, желающие получить в дальнейшем доступ к этому объекту, должны указывать тот же самый ключ.

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

Генерация ключей: функция ftok().

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

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

#include <sys/types.h>

#include <sys/ipc.h>

key_t ftok(char *filename, char proj);

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

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

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