2

我正在编写一个 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;
}

谢谢,
亚历克斯

4

1 回答 1

2

在 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]);
}
于 2013-11-14T16:21:14.987 回答