2015-10-18 2 views
1

От PHP, он говоритshmop_open Каков ключевой параметр?

INT shmop_open (интермедиат $ ключ, строка $ флаги, режим INT $, INT $ размер)

где $ ключ является

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

Некоторые люди заполняют ключ $ произвольным числом (1), в то время как другие используют файл для получения значения ключа $ (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); 

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

ответ

2

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

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

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

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

См How to choose the "Key" for inter-processes communication in Linux?

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

Одна вещь, которая кажется странным для меня является то, что реализация 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.