Php: removing shared memory on windows

This code:

shmop_delete(); shmop_close(); 

does not delete shared memory. Experiment:

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

gives

 bool(false) 

sure. But

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

gives

 int(157) 

Why not deleted yet? How to delete shared memory? I am running apache on windows 7.

+4
source share
1 answer

SHM is not natively available on Windows, so PHP is trying to emulate it in its "thread-safe resource manager" (TSRM) using internal Windows File Mappings, which is an ugly hack (/TSRM/tsrm_win32.c).

Consequently, the shmop extension also uses TSRM for SHM on Windows systems. shmop_delete() uses shmctl() with the IPC_RMID command to mark a memory segment, but IPC_RMID implemented as follows in the emulation:

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

where shm_nattch is the number of processes to which the segment is attached (or at least what, according to TSRM). By setting shm_perm.key to -1, subsequent access using shmget() blocked until the Windows file association is destroyed. However, when this code is called from shmop_delete() , always at least the PHP process itself is bound to a memory segment, so it actually does nothing. A segment is only separated after calling shmop_close()

So your answer is: without fixing PHP, on Windows you cannot delete shared memory.

You can accuse him of emulating SHM in TSRM, which is not correctly fixed, or on the shmop extension for blind use.

You can try to remove if and set shm_perm.key to -1 unconditionally and recompile PHP. It can only break the shmop extension, the sysvshm extension, or possibly other extensions not distributed with PHP.

Feel free to report this to the PHP bugtracker at http://bugs.php.net/ and fix it by someone more familiar with the internal components of PHP.

In the meantime, perhaps http://www.php.net/w32api can help - you can use CreateFileMapping and friends from the Win32-API in a more direct way with this. However, I have never tested it, and in PECL it says that it is not supported, so be careful. It is also, of course, not portable.

You can also try wrapping the shmop_* in your own library and putting your own remote flag at the beginning of the memory segment - TSRM will still do something similar inside. But then you may encounter a related error: I think I remember someone reporting that he was unable to create a segment with shmop_open() , which was larger than the last segment created using the same key.

+5
source

Source: https://habr.com/ru/post/1433665/


All Articles