shmop_open, что является ключевым параметром?

1

Из PHP это говорит

int shmop_open (int $ key, string $ flags, int $ mode, int $ size)

где $ key - это

Идентификатор системы для блока разделяемой памяти. Может быть передано как десятичное или шестнадцатеричное.

Некоторые люди заполняют ключ $ произвольным числом (1), в то время как другие используют файл для получения значения $ key (2). Является ли ключ $ случайным значением?.

(1)

   $shm_id = shmop_open(987654, "c", 0644, 100);

(2)

   $shm_key = ftok(__FILE__, 't');
   $shm_id = shmop_open($shm_key, "c", 0644, 100);

Кстати, в окнах я использовал небольшое число, и пока он работал, я был ограничен использованием до 1024 байт. При использовании большого числа для ключа я смог адресовать больше памяти. Зачем?.

Теги:
shared-memory

1 ответ

3

Если вы просмотрите источник shmop_open(), вы увидите, что функция в основном представляет собой оболочку вокруг shmget() POSIX shmget(), shmctl() и shmat(). Вы можете видеть, что параметр $key для shmop_open() передается как ключ IPC System V для shmget().

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

Вы можете использовать фиксированный ключ, как и первый пример, который вы указали. Однако использование фиксированных ключей подвержено непреднамеренным столкновениям.

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

См. Как выбрать "ключ" для взаимодействия между процессами в Linux?

PHP в Windows не поддерживает функции общей памяти. Вместо этого они эмулируются через "поточный менеджер ресурсов" (TSRM). Вы можете найти реализацию shmget() в TSRM/tsrm_win32.c. Известно, что эмуляция разделяемой памяти TSRM несколько причудлива (например, см. Этот ответ).

Мне кажется странным, что реализация TSMM shmget() создает имя сопоставления файлов Windows, представляющее сегмент разделяемой памяти, посредством:

char shm_segment[26], shm_info[29];
/* ... */
snprintf(shm_segment, sizeof(shm_segment)-1, "TSRM_SHM_SEGMENT:%d", key);

Поскольку длина "TSRM_SHM_SEGMENT:" равна 17, и этот вызов snprintf() будет содержать не более 24 символов, это оставляет только 7 символов для ключа. Таким образом, похоже, что только ключи между -999999 и 9999999 включительно должны использоваться с PHP в Windows.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню