加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php:删除Windows上的共享内存

发布时间:2020-12-13 17:21:07 所属栏目:PHP教程 来源:网络整理
导读:这段代码: shmop_delete();shmop_close(); 不删除共享内存.一个实验: $shmid = @shmop_open(1234,'a',0);var_dump($shmid); 产量 bool(false) 当然.但 $shmid = shmop_open(5678,'c',0644,10);...shmop_delete($shmid);shmop_close($shmid);...$shmid = @s
这段代码:

shmop_delete();
shmop_close();

不删除共享内存.一个实验:

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

产量

bool(false)

当然.但

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

产量

int(157)

为什么不删除呢?如何删除共享内存?我在Windows 7上运行apache.

解决方法

SHM在Windows中本身不可用,因此PHP尝试在其“线程安全资源管理器”(TSRM)中通过内部使用Windows文件映射来模拟它,这是一个丑陋的黑客(/TSRM/tsrm_win32.c).

因此,shmop扩展也在Windows系统上使用TSRM for SHM.
shmop_delete()使用带有IPC_RMID命令的shmctl()来标记销毁的内存段,但是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.keyto -1,shmget()的后续访问将被阻止,直到Windows文件映射被销毁.但是,当从shmop_delete()调用此代码时,始终至少PHP进程本身附加到内存段,因此它实际上什么都不做.调用shmop_close()后,该段仅被分离

所以你的答案是:在没有修复PHP的情况下,在Windows上,你无法删除共享内存.

您可以将其归咎于TSRM中的SHM仿真,这不是正确的,或者在shmop扩展上用于盲目使用它.

您可以尝试删除if并无条件地将shm_perm.key设置为-1并重新编译PHP.它只能破坏shmop扩展本身,sysvshm扩展或可能不与PHP一起分发的其他扩展.

请在http://bugs.php.net/向PHP bugtracker报告,并由更熟悉PHP内部的人修复.

在此期间,也许http://www.php.net/w32api可以提供帮助 – 您可以使用CreateFileMapping&来自Win32-API的朋友可以更直接地使用它.但是,我从来没有对它进行过测试,在PECL中它说它没有被维护,所以要小心.它当然也不便携.

你也可以尝试将shmop_ *东西包装到你自己的库中,并将你自己的deleted-flag放在内存段的开头 – 毕竟TSRM在内部执行类似的操作.但是你可能遇到一个相关的错误:我想我记得有人报告说他无法使用shmop_open()创建一个比使用相同键创建的最后一个段更大的段.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读