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 &#61; SW_STRING_BUFFER_DEFAULT;//解析输入参数&#xff0c;这里输入参数用来指定要申请的内存空间大小&#xff0c;如果用户侧不设置&#xff0c;默认取SW_STRING_BUFFER_DEFAULT&#xff0c;其值为128if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) &#61;&#61; FAILURE){RETURN_FALSE;}if (size <1)//size有效性检查{zend_throw_exception(swoole_exception_class_entry_ptr, "buffer size can&#39;t be less than 0.", SW_ERROR_INVALID_PARAMS TSRMLS_CC);RETURN_FALSE;}else if (size > SW_STRING_BUFFER_MAXLEN)//最大空间限制为SW_STRING_BUFFER_MAXLEN&#xff0c;其值为128M{zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "buffer size can&#39;t exceed %d", SW_STRING_BUFFER_MAXLEN);RETURN_FALSE;}swString *buffer &#61; swString_new(size);//申请size大小的内存空间&#xff0c;其实现在下面分析if (buffer &#61;&#61; 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属性&#xff0c;取值为sizezend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), 0 TSRMLS_CC);//设置swoole_buffer的length属性&#xff0c;取值为0&#xff0c;即表示目前还没使用这个空间
}
swString *swString_new(size_t size)
{swString *str &#61; sw_malloc(sizeof(swString));//申请swString对象内存&#xff0c;大小为sizeof(swString)if (str &#61;&#61; NULL)//申请失败{swWarn("malloc[1] failed.");return NULL;}bzero(str, sizeof(swString));//空间初始化str->size &#61; size;//设定size属性str->str &#61; sw_malloc(size);//申请str内存空间if (str->str &#61;&#61; NULL)//申请失败{swSysError("malloc[2](%ld) failed.", size);sw_free(str);return NULL;}return str;
}
#ifdef SW_USE_JEMALLOC //如果可以使用jemalloc
#include
#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