Какой смысл иметь key_t, если ключом доступа к разделяемой памяти будет возвращаемое значение shmget ()? - PullRequest
13 голосов
/ 14 ноября 2010

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

key_t ftok(const char *path, int id);

в следующем бите кода?

key_t key;
int shmid;

key = ftok("/home/beej/somefile3", 'R');
shmid = shmget(key, 1024, 0644 | IPC_CREAT);

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

Редактировать

@ Руководство Beej по Unix IPC можно прочитать:

Как насчет этой key чепухи? Как мы создаем один? Ну так как типа key_t на самом деле просто long, вы можете используйте любой номер, который вы хотите. Но что, если Вы жестко набираете номер и некоторые другие не связанные программы жестко тот же номер, но хочет другую очередь? Решение состоит в том, чтобы использовать ftok() функция, которая генерирует ключ из два аргумента.

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

Ответы [ 3 ]

13 голосов
/ 14 ноября 2010

Вся система System V IPC полна плохих конструкций, подобных этой. (Под плохим дизайном я подразумеваю крошечное пространство имен для общих ресурсов, где вам приходится полагаться на глупые уловки, такие как ftok, чтобы получить ключ и молиться, чтобы это не конфликтовало с другими используемыми ключами.)

Если возможно, я бы сделал вид, что его не существует, и вместо этого использовал бы общую память POSIX, когда это возможно (а также примитивы синхронизации потоков POSIX вместо семафоров System V). Единственный случай, когда я могу вспомнить, где вам нужна общая память System V, - это расширение образа совместно используемой памяти X и, возможно, другие расширения X.

Редактировать: Чтобы лучше ответить на вопрос ОП о назначении ftok: key_t обычно является 32-разрядным, и да, вы можете просто выбрать 32-разрядное число самостоятельно, но проблема в том, что люди не могут одинаково выбрать все числа, и вероятность столкновения слишком высока. ftok позволяет вам выбрать файл (который должен быть уникальным для вашего приложения), целое число и хэшировать номер инода файла с выбранным вами целым числом, что должно привести к гораздо более равномерному распределению выбора ключей по пространству клавиш. Конечно, вы также можете просто выбрать ключ с rand, если у вас есть возможность передать результат другим процессам, которым необходимо подключить разделяемую память.

11 голосов
/ 14 ноября 2010

Да, вам нужно использовать shmid для доступа к общей памяти (используя shmat()) после того, как вы открыли ее, используя shmget(). Но конкретный блок разделяемой памяти, к которому вы будете обращаться, основан на ключе, который вы используете, то есть другой процесс, желающий общаться через shm, должен будет использовать тот же ключ. Если вы просто использовали случайное число в качестве ключа, вы можете столкнуться с какой-то другой не связанной программой.

Я собирался предложить взглянуть на Руководство Beej по IPC , но я вижу, вы уже нашли его:)

1 голос
/ 14 ноября 2010

shmid значения действительны только в контексте одного процесса, в то время как одно и то же значение key_t в разных процессах позволит им открывать один и тот же сегмент совместно используемой памяти.

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

...