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