PHP C 扩展全局内存管理

标签 php php-extension

我正在编写一个 C 扩展,它应该在模块初始化时分配一个全局数组(该数组不会更改并且与每个请求相关)。我读过有关 php c 扩展内存管理的内容,但大多数资料都没有提到在堆栈上声明变量。

这仍然是一种有效的方法,还是更有可能泄漏,在这种情况下我应该更喜欢 pemalloc 等......?

一些示例代码来说明问题:
在我的标题中:

ZEND_BEGIN_MODULE_GLOBALS(myExtension)
long long myArray[ARRAY_SIZE];
ZEND_END_MODULE_GLOBALS(myExtension)

在实现中:

PHP_MINIT_FUNCTION(myExtension) {
    fillUpMyArray();
    return SUCCESS;
}

谢谢,
亚历克斯

最佳答案

PHP 扩展中基本上有两种不同类型的内存使用情况:

  • 线程本地存储,用 zend 的话说就是“线程安全全局”变量,在特定请求期间可用;
    需要在 ZEND_GINIT_FUNCTION(myExtension) 中设置并在 ZEND_GSHUTDOWN_FUNCTION(myExtension) 中拆除 [ZEND_MODULE_API_NO >=20060613, php >=5.2.0 时可用]
  • 进程范围存储,即术语“持久数据”;
    需要静态设置和/或在 ZEND_MINIT_FUNCTION(myExtension) 中设置,并静态拆除和/或在 ZEND_MSHUTDOWN_FUNCTION(myExtension)

使用 ZEND_BEGIN_MODULE_GLOBALS 宏声明线程安全的全局变量,您真正想要的是持久数据。

(!) 请注意,php 只知道数据类型 long,而不是 long long

您没有告诉的是您到底如何使用数组。
对于您的具体情况,您可以简单地使用 .c/.cpp 文件中定义的静态数组以及数组访问函数:

static long myArray[ARRAY_SIZE];

ZEND_MINIT_FUNCTION(myExtension)
{
    fillUpMyArray();
    return SUCCESS;
}

ZEND_FUNCTION(myext_get)
{
    long idx;

    if (zend_parse_parameters_ex(0, ZEND_NUM_ARGS() TSRMLS_CC, "l", &idx) == FAILURE)
        RETURN_NULL();

    // TODO check array bounds!

    RETURN_LONG(myArray[idx]);
}

关于PHP C 扩展全局内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17580182/

相关文章:

php - 使用自制软件在 Mac Big Sur 上为 PHP 7.3.24 安装 pgsql 扩展时出现问题

PHP/MYSQL 通过 ID 只获取一列值

PHP 拆分字符串异常

php - SQL中的一对多关系 - 外键错误

javascript - 使用从 PHP 脚本获取的 Javascript 数组

php - 在 win32 c 扩展中使用 php_strtolower

javascript - 如何在 Laravel 中拆分或分离序列化表单数据

linux - Pecl Swoole php插件在linux centos上安装失败

php - 在 PHP-CPP 中将 Php::Object 转换回 C++ 对象?

php - 无法在Docker中安装MongoDB PHP扩展