php: удаление разделяемой памяти на окнах

Этот код:

shmop_delete(); shmop_close(); 

не удаляет разделяемую память. Эксперимент:

 $shmid = @shmop_open(1234, 'a', 0, 0); var_dump($shmid); 

доходность

 bool(false) 

конечно. Но

 $shmid = shmop_open(5678, 'c', 0644, 10); ... shmop_delete($shmid); shmop_close($shmid); ... $shmid = @shmop_open(5678, 'a', 0, 0); var_dump($shmid); 

доходность

 int(157) 

Почему еще не удалены? Как удалить общую память? Я запускаю apache в Windows 7.

Solutions Collecting From Web of "php: удаление разделяемой памяти на окнах"

SHM не доступен изначально в Windows, поэтому PHP пытается эмулировать его в своем «поточно-безопасном диспетчере ресурсов» (TSRM), используя внутренние файлы Windows File Mappings, что является уродливым взломом (/TSRM/tsrm_win32.c).

Поэтому расширение shmop также использует TSRM для SHM в системах Windows. shmop_delete() использует shmctl() с командой IPC_RMID для уничтожения сегмента памяти, однако IPC_RMID реализуется следующим образом в эмуляции:

  switch (cmd) { [...] case IPC_RMID: if (shm->descriptor->shm_nattch < 1) { shm->descriptor->shm_perm.key = -1; } return 0; 

где shm_nattch – количество процессов, к которым сегмент привязан (или, по крайней мере, то, что, по мнению TSRM). Установив shm_perm.key в -1, последующий доступ shmget() блокируется до тех пор, пока не будет уничтожено сопоставление файлов Windows. Однако, когда этот код вызывается из shmop_delete() , всегда есть, по крайней мере, сам процесс PHP, привязанный к сегменту памяти, поэтому он фактически ничего не делает. Сегмент отделяется только после вызова shmop_close()

Итак, ваш ответ: без исправления PHP, в Windows вы не можете удалить общую память.

Вы можете обвинить его либо в эмуляции SHM в TSRM, которая не является правильно исправленной, либо на расширении shmop для слепого использования.

Вы можете попытаться удалить if и установить shm_perm.key на -1 безоговорочно и перекомпилировать PHP. Он может только сломать расширение shmop, расширение sysvshm или, возможно, другие расширения, не распространяемые с PHP.

Не стесняйтесь сообщать об этом в PHP bugtracker по адресу http://bugs.php.net/ и исправлять его кем-то, знакомым с внутренними компонентами PHP.

Тем временем, может быть, http://www.php.net/w32api может помочь – вы могли бы использовать CreateFileMapping и друзей из Win32-API более прямым образом с ним. Тем не менее, я никогда не тестировал его, и в PECL он говорит, что он не поддерживается, поэтому будьте осторожны. Это также, конечно, не переносимо.

Вы также можете попытаться обернуть материал shmop_* в свою собственную библиотеку и поместить свой собственный удаленный флаг в начале сегмента памяти – TSRM все-таки сделает что-то подобное внутри. Но тогда вы можете столкнуться с связанной ошибкой: я думаю, что я помню, как кто-то сообщал, что он не мог создать сегмент с shmop_open() который был больше, чем последний сегмент, созданный с использованием того же ключа.