Из 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 байт. При использовании большого числа для ключа я смог адресовать больше памяти. Зачем?.
Если вы просмотрите источник 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.