UNIX: взаимодействие процессов
Шрифт:
На самом деле функция использует полное имя файла и младшие 8 бит идентификатора для формирования целочисленного ключа IPC.
Эта функция действует в предположении, что для конкретного приложения, использующего IPC, клиент и сервер используют одно и то же полное имя объекта IPC, имеющее какое-то значение в контексте приложения. Это может быть имя демона сервера или имя файла данных, используемого сервером, или имя еще какого-нибудь объекта файловой системы. Если клиенту и серверу для
Большинство реализаций ftok вызывают функцию stat, а затем объединяют:
■ информацию о файловой системе, к которой относится полное имя pathname (поле st_dev структуры stat);
■ номер узла (i-node) в файловой системе (поле st_ino структуры stat);
■ младшие 8 бит идентификатора (который не должен равняться нулю).
Из комбинации этих трех значений обычно получается 32-разрядный ключ. Нет никакой гарантии того, что для двух различных путей с одним и тем же идентификатором получатся разные ключи, поскольку количество бит информации в трех перечисленных элементах (идентификатор файловой системы, номер узла, идентификатор IPC) может превышать число бит в целом (см. упражнение 3.5).
ПРИМЕЧАНИЕ
Номер узла всегда отличен от нуля, поэтому большинство реализаций определяют константу IPC_PRIVATE (раздел 3.4) равной нулю.
Если указанное полное имя не существует или недоступно вызывающему процессу, ftok возвращает значение –1. Помните, что файл, имя которого используется для вычисления ключа, не должен быть одним из тех, которые создаются и удаляются сервером в процессе работы, поскольку каждый раз при создании заново эти файлы получают, вообще говоря, другой номер узла, а это может изменить ключ, возвращаемый функцией ftok при очередном вызове.
Пример
Программа в листинге 3.1 принимает полное имя в качестве аргумента командной строки, вызывает функции stat и ftok, затем выводит значения полей st_dev и st_ino структуры stat и получающийся ключ IPC. Эти три значения выводятся в шестнадцатеричном формате, поэтому легко видеть, как именно ключ IPC формируется из этих двух значений и идентификатора 0x57.
1
Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.
Выполнение
этой программы в системе Solaris 2.6 приведет к следующим результатам:Очевидно, идентификатор определяет старшие 8 бит ключа; младшие 12 бит st_dev определяют следующие 12 бит ключа, и наконец, младшие 12 бит st_ino определяют младшие 12 бит ключа.
Цель этого примера не в том, чтобы впоследствии рассчитывать на такой способ формирования ключа из перечисленной информации, а в том, чтобы проиллюстрировать алгоритм комбинации полного имени и идентификатора конкретной реализацией. В других реализациях алгоритм может быть другим.
ПРИМЕЧАНИЕ
В FreeBSD используются младшие 8 бит идентификатора, младшие 8 бит st_dev и младшие 16 бит st_ino.
Учтите, что отображение, производимое функцией ftok, — одностороннее, поскольку часть бит st_dev и st_ino не используются. По данному ключу нельзя определить полное имя файла, заданное для вычислений.
3.3. Структура ipc_perm
Для каждого объекта IPC, как для обычного файла, в ядре хранится набор информации, объединенной в структуру.
Эта структура вместе с другими переименованными константами для функций System V IPC определена в файле <sys/ipc.h>. В этой главе мы расскажем о полях структуры ipc_perm более подробно.
3.4. Создание и открытие каналов IPC
Три функции getXXX, используемые для создания или открытия объектов IPC (табл. 3.1), принимают ключ IPC (типа key_t) в качестве одного из аргументов и возвращают целочисленный идентификатор. Этот идентификатор отличается от того, который передавался функции ftok, как мы вскоре увидим. У приложения есть две возможности задания ключа (первого аргумента функций getXXX):
1. Вызвать ftok, передать ей полное имя и идентификатор.
2. Указать в качестве ключа константу IPCPRIVATE, гарантирующую создание нового уникального объекта IPC.
Последовательность действий иллюстрирует рис. 3.1.
Рис. 3.1. Вычисление идентификаторов IPC по ключам
Все три функции getXXX (табл. 3.1) принимают в качестве второго аргумента набор флагов oflag, задающий биты разрешений чтения-записи (поле mode структуры ipc_perm) для объекта IPC и определяющий, создается ли новый объект IPC или производится обращение к уже существующему. Для этого имеются следующие правила.