草庐IT

php:删除Windows上的共享内存

coder 2024-04-15 原文

这段代码:

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)

为什么还没有删除?如何删除共享内存?我在 Windows 7 上运行 Apache。

最佳答案

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

因此,shmop 扩展也在 Windows 系统上使用 TSRM for SHM。 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 上,你不能删除共享内存。

您可以将其归咎于 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 的 friend 。然而,我从来没有测试过它,在 PECL 中它说它没有维护,所以要小心。它当然也是不可移植的。

您还可以尝试将 shmop_* 内容包装到您自己的库中,并将您自己的 deleted-flag 放在内存段的开头 - 毕竟 TSRM 在内部做了类似的事情。但是随后您可能会遇到一个相关的错误:我想我记得有人报告说他无法使用 shmop_open() 创建比使用相同 key 创建的最后一个段更大的段。

关于php:删除Windows上的共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12378098/

有关php:删除Windows上的共享内存的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  4. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  5. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  10. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

随机推荐