От PHP это говорит
int shmop_open (int $ key, string $ flags, int $ mode, int $ size)
где $ key является
Идентификатор системы для блока общей памяти. Может быть передано как десятичное или шестнадцатеричное.
Некоторые люди заполняют $ key произвольным числом (1), в то время как другие используют файл для получения значения $ key (2). Является ли $ key случайным значением?
(1)
$shm_id = shmop_open(987654, "c", 0644, 100);
(2)
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, "c", 0644, 100);
Кстати, в Windows я использовал небольшое количество, и пока он работал, я был ограничен использованием до 1024 байтов. Используя большое число для ключа, я смог адресовать больше памяти. Зачем?.
Если вы посмотрите через источник shmop_open()
, вы увидите, что эта функция в основном является оболочкой для POSIX shmget()
, shmctl()
, а также shmat()
Подпрограммы. Вы можете видеть, что $key
параметр для shmop_open()
передается как ключ System V IPC shmget()
,
shmget()
возвращает идентификатор сегмента разделяемой памяти, связанного с данным ключом. Если ключ передан shmget()
это особая ценность IPC_PRIVATE
, то это относится к уникальному сегменту разделяемой памяти, который может быть унаследован только потомками, созданными fork()
(Обратите внимание, что это, вероятно, не относится к вашему делу). В противном случае, чтобы два процесса получили доступ к одному и тому же сегменту совместно используемой памяти, им необходимо получить идентификатор этого сегмента, используя один и тот же ключ.
Вы можете использовать фиксированный ключ, как в первом приведенном вами примере. Однако использование фиксированных ключей склонно к случайным столкновениям.
Лучший подход заключается в использовании ftok()
. Если вы постоянно используете ftok()
чтобы сгенерировать ключ, то риск столкновения ниже в результате ftok()
Гарантия того, что сгенерированный ключ будет отличаться при вызове с разными значениями идентификатора или с путями, которые называют два разных файла, существующих в одной и той же файловой системе одновременно.
Увидеть Как выбрать "ключ" для межпроцессного взаимодействия в Linux?
PHP на Windows изначально не поддерживает функции совместно используемой памяти. Вместо этого они эмулируются через «поточно-ориентированный менеджер ресурсов» (TSRM). Ты можешь найти реализация TSRM shmget()
в TSRM/tsrm_win32.c
, Известно, что эмуляция разделяемой памяти TSRM выглядит несколько странно (например, см. этот ответ).
Мне кажется странным то, что TSRM 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.
Других решений пока нет …