swoole原始碼解析之swoole_buffer的建立過程
阿新 • • 發佈:2018-12-13
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