版权声明:转载请注明来源 https://blog.csdn.net/u013702678/article/details/82951884
swoole提供了一个swoole_buffer类(代码位于swoole_buffer.c中),让PHP开发者可以像C一样直接读写内存,提升程序的性能,又不用担心内存越界。swoole_buffer会检测offset,但是swoole_buffer提供的内存空间不是共享内存形式的,不可以在多个进程间共享,swoole_buffer提供了两个属性如下。
- swoole_buffer->$length,当前数据的长度
- swoole_buffer->$capacity,当前缓存区的容量
创建一个内存对象。函数原型:
swoole_buffer->__construct(int $size = 128);
参数$size指定了缓冲区内存的初始尺寸。当申请的内存容量不够时swoole底层会自动扩容。
下面我们看看其构造过程。
static PHP_METHOD(swoole_buffer, __construct)
{
long size = SW_STRING_BUFFER_DEFAULT;
//解析输入参数,这里输入参数用来指定要申请的内存空间大小,如果用户侧不设置,默认取SW_STRING_BUFFER_DEFAULT,其值为128
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) == FAILURE)
{
RETURN_FALSE;
}
if (size < 1)//size有效性检查
{
zend_throw_exception(swoole_exception_class_entry_ptr, "buffer size can't be less than 0.", SW_ERROR_INVALID_PARAMS TSRMLS_CC);
RETURN_FALSE;
}
else if (size > SW_STRING_BUFFER_MAXLEN)//最大空间限制为SW_STRING_BUFFER_MAXLEN,其值为128M
{
zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "buffer size can't exceed %d", SW_STRING_BUFFER_MAXLEN);
RETURN_FALSE;
}
swString *buffer = swString_new(size);//申请size大小的内存空间,其实现在下面分析
if (buffer == NULL)
{
zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "malloc(%ld) failed.", size);
RETURN_FALSE;
}
swoole_set_object(getThis(), buffer);//建立PHP侧的对象swoole_buffer和swoole内部对象buffer的对应关系
zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), size TSRMLS_CC);//设置swoole_buffer的capacity属性,取值为size
zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), 0 TSRMLS_CC);//设置swoole_buffer的length属性,取值为0,即表示目前还没使用这个空间
}
swString *swString_new(size_t size)
{
swString *str = sw_malloc(sizeof(swString));//申请swString对象内存,大小为sizeof(swString)
if (str == NULL)//申请失败
{
swWarn("malloc[1] failed.");
return NULL;
}
bzero(str, sizeof(swString));//空间初始化
str->size = size;//设定size属性
str->str = sw_malloc(size);//申请str内存空间
if (str->str == NULL)//申请失败
{
swSysError("malloc[2](%ld) failed.", size);
sw_free(str);
return NULL;
}
return str;
}
#ifdef SW_USE_JEMALLOC //如果可以使用jemalloc
#include <jemalloc/jemalloc.h>
#define sw_malloc je_malloc//sw_malloc通过je_malloc实现
#define sw_free je_free
#define sw_calloc je_calloc
#define sw_realloc je_realloc
#else
#define sw_malloc malloc//通过默认的malloc实现
#define sw_free free
#define sw_calloc calloc
#define sw_realloc realloc
#endif