swoole源码解析之swoole_buffer的创建过程

版权声明:转载请注明来源 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

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/82951884