国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Swoole 源碼分析——內(nèi)存模塊之swBuffer

fyber / 1564人閱讀

摘要:的數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)中是鏈表元素的個(gè)數(shù),是緩沖區(qū)創(chuàng)建時(shí),鏈表元素約定的大小實(shí)際大小不一定是這個(gè)值,是實(shí)際上緩沖區(qū)占用的內(nèi)存總大小。中的有三種,分別應(yīng)用于緩存數(shù)據(jù)發(fā)送文件提醒連接關(guān)閉三種情景。指的是元素的內(nèi)存大小。

前言

swoole 中數(shù)據(jù)的接受與發(fā)送(例如 reactor 線程接受客戶端消息、發(fā)送給客戶端的消息、接受到的來自 worker 的消息、要發(fā)送給 worker 的消息等等)都要涉及到緩沖區(qū),swoole 中的緩沖區(qū)實(shí)現(xiàn)是 swBuffer,實(shí)際上是一個(gè)單鏈表。

swBuffer 的數(shù)據(jù)結(jié)構(gòu)

swBuffer 數(shù)據(jù)結(jié)構(gòu)中 trunk_num 是鏈表元素的個(gè)數(shù),trunk_sizeswBuffer 緩沖區(qū)創(chuàng)建時(shí),鏈表元素約定的大小(實(shí)際大小不一定是這個(gè)值),length 是實(shí)際上緩沖區(qū)占用的內(nèi)存總大小。

swBuffer_trunk 中的 type 有三種,分別應(yīng)用于:緩存數(shù)據(jù)、發(fā)送文件、提醒連接關(guān)閉三種情景。length 指的是元素的內(nèi)存大小。

enum swBufferChunk
{
    SW_CHUNK_DATA,
    SW_CHUNK_SENDFILE,
    SW_CHUNK_CLOSE,
};

typedef struct _swBuffer_trunk
{
    uint32_t type;
    uint32_t length;
    uint32_t offset;
    union
    {
        void *ptr;
        struct
        {
            uint32_t val1;
            uint32_t val2;
        } data;
    } store;
    uint32_t size;
    void (*destroy)(struct _swBuffer_trunk *chunk);
    struct _swBuffer_trunk *next;
} swBuffer_trunk;

typedef struct _swBuffer
{
    int fd;
    uint8_t trunk_num; //trunk數(shù)量
    uint16_t trunk_size;
    uint32_t length;
    swBuffer_trunk *head;
    swBuffer_trunk *tail;
} swBuffer;
swBuffer 的創(chuàng)建

swBuffer 的創(chuàng)建很簡(jiǎn)單,只是初始化整個(gè) swBufferheader 頭元素而已:

swBuffer* swBuffer_new(int trunk_size)
{
    swBuffer *buffer = sw_malloc(sizeof(swBuffer));
    if (buffer == NULL)
    {
        swWarn("malloc for buffer failed. Error: %s[%d]", strerror(errno), errno);
        return NULL;
    }

    bzero(buffer, sizeof(swBuffer));
    buffer->trunk_size = trunk_size;

    return buffer;
}
swBuffer 內(nèi)存的申請(qǐng)

swBuffer 內(nèi)存的申請(qǐng)邏輯也很簡(jiǎn)單,按照傳入的 size 參數(shù)為鏈表元素申請(qǐng)內(nèi)存,初始化成員變量,然后將鏈表元素放到鏈表的尾部即可:

int swBuffer_append(swBuffer *buffer, void *data, uint32_t size)
{
    swBuffer_trunk *chunk = swBuffer_new_trunk(buffer, SW_CHUNK_DATA, size);
    if (chunk == NULL)
    {
        return SW_ERR;
    }

    buffer->length += size;
    chunk->length = size;

    memcpy(chunk->store.ptr, data, size);

    swTraceLog(SW_TRACE_BUFFER, "trunk_n=%d|size=%d|trunk_len=%d|trunk=%p", buffer->trunk_num, size,
            chunk->length, chunk);

    return SW_OK;
}

swBuffer_trunk *swBuffer_new_trunk(swBuffer *buffer, uint32_t type, uint32_t size)
{
    swBuffer_trunk *chunk = sw_malloc(sizeof(swBuffer_trunk));
    if (chunk == NULL)
    {
        swWarn("malloc for trunk failed. Error: %s[%d]", strerror(errno), errno);
        return NULL;
    }

    bzero(chunk, sizeof(swBuffer_trunk));

    //require alloc memory
    if (type == SW_CHUNK_DATA && size > 0)
    {
        void *buf = sw_malloc(size);
        if (buf == NULL)
        {
            swWarn("malloc(%d) for data failed. Error: %s[%d]", size, strerror(errno), errno);
            sw_free(chunk);
            return NULL;
        }
        chunk->size = size;
        chunk->store.ptr = buf;
    }

    chunk->type = type;
    buffer->trunk_num ++;

    if (buffer->head == NULL)
    {
        buffer->tail = buffer->head = chunk;
    }
    else
    {
        buffer->tail->next = chunk;
        buffer->tail = chunk;
    }

    return chunk;
}
獲取 swBuffer 的元素

swBuffer 緩沖區(qū)拿數(shù)據(jù)只能從 head 中獲取:

#define swBuffer_get_trunk(buffer)   (buffer->head)
swBuffer 元素的 pop

獲取了緩沖區(qū)的元素之后,就要相應(yīng)刪除 head 鏈表元素:

void swBuffer_pop_trunk(swBuffer *buffer, swBuffer_trunk *chunk)
{
    if (chunk->next == NULL)
    {
        buffer->head = NULL;
        buffer->tail = NULL;
        buffer->length = 0;
        buffer->trunk_num = 0;
    }
    else
    {
        buffer->head = chunk->next;
        buffer->length -= chunk->length;
        buffer->trunk_num--;
    }
    if (chunk->type == SW_CHUNK_DATA)
    {
        sw_free(chunk->store.ptr);
    }
    if (chunk->destroy)
    {
        chunk->destroy(chunk);
    }
    sw_free(chunk);
}
swBuffer 緩沖區(qū)的銷毀
int swBuffer_free(swBuffer *buffer)
{
    volatile swBuffer_trunk *chunk = buffer->head;
    void * *will_free_trunk;  //free the point
    while (chunk != NULL)
    {
        if (chunk->type == SW_CHUNK_DATA)
        {
            sw_free(chunk->store.ptr);
        }
        will_free_trunk = (void *) chunk;
        chunk = chunk->next;
        sw_free(will_free_trunk);
    }
    sw_free(buffer);
    return SW_OK;
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/29221.html

相關(guān)文章

  • Swoole 源碼分析——Reactor模塊ReactorBase

    前言 作為一個(gè)網(wǎng)絡(luò)框架,最為核心的就是消息的接受與發(fā)送。高效的 reactor 模式一直是眾多網(wǎng)絡(luò)框架的首要選擇,本節(jié)主要講解 swoole 中的 reactor 模塊。 UNP 學(xué)習(xí)筆記——IO 復(fù)用 Reactor 的數(shù)據(jù)結(jié)構(gòu) Reactor 的數(shù)據(jù)結(jié)構(gòu)比較復(fù)雜,首先 object 是具體 Reactor 對(duì)象的首地址,ptr 是擁有 Reactor 對(duì)象的類的指針, event_nu...

    baukh789 評(píng)論0 收藏0
  • Swoole 源碼分析——Server模塊ReactorThread事件循環(huán)(下)

    摘要:之后如果仍然有剩余未發(fā)送的數(shù)據(jù),那么就如果已經(jīng)沒有剩余數(shù)據(jù)了,繼續(xù)去取下一個(gè)數(shù)據(jù)包。拿到后,要用函數(shù)轉(zhuǎn)化為相應(yīng)的類型即可得到包長(zhǎng)值。 swPort_onRead_check_eof EOF 自動(dòng)分包 我們前面說過,swPort_onRead_raw 是最簡(jiǎn)單的向 worker 進(jìn)程發(fā)送數(shù)據(jù)包的方法,swoole 會(huì)將從客戶端接受到的數(shù)據(jù)包,立刻發(fā)送給 worker 進(jìn)程,用戶自己把...

    Maxiye 評(píng)論0 收藏0
  • Swoole 源碼分析——Server模塊ReactorThread事件循環(huán)(上)

    摘要:線程在建立之時(shí),就會(huì)調(diào)用函數(shù)開啟事件循環(huán)。如果為空,那么重新設(shè)置文件描述符的監(jiān)聽事件,刪除寫就緒,只設(shè)置讀就緒。這個(gè)是水平觸發(fā)模式的必要步驟,避免無數(shù)據(jù)寫入時(shí),頻繁地調(diào)用寫就緒回調(diào)函數(shù)。 前言 經(jīng)過 php_swoole_server_before_start 調(diào)用 swReactorThread_create 創(chuàng)建了 serv->reactor_threads 對(duì)象后,swServe...

    gplane 評(píng)論0 收藏0
  • Swoole 源碼分析——Server模塊Timer模塊與時(shí)間輪算法

    摘要:當(dāng)其就緒時(shí),會(huì)調(diào)用執(zhí)行定時(shí)函數(shù)。進(jìn)程超時(shí)停止進(jìn)程將要停止時(shí),并不會(huì)立刻停止,而是會(huì)等待事件循環(huán)結(jié)束后停止,這時(shí)為了防止進(jìn)程不退出,還設(shè)置了的延遲,超過就會(huì)停止該進(jìn)程。當(dāng)允許空閑時(shí)間小于時(shí),統(tǒng)一每隔檢測(cè)空閑連接。 前言 swoole 的 timer 模塊功能有三個(gè):用戶定時(shí)任務(wù)、剔除空閑連接、更新 server 時(shí)間。timer 模塊的底層有兩種,一種是基于 alarm 信號(hào),一種是基于...

    qieangel2013 評(píng)論0 收藏0
  • Swoole 源碼分析——內(nèi)存模塊共享內(nèi)存

    摘要:前言我們知道,由于沒有多線程模型,所以更多的使用多進(jìn)程模型,因此代碼相對(duì)來說更加簡(jiǎn)潔,減少了各種線程鎖的阻塞與同步,但是也帶來了新的問題數(shù)據(jù)同步。相比多線程之前可以直接共享進(jìn)程的內(nèi)存,進(jìn)程之間數(shù)據(jù)的相互同步依賴于共享內(nèi)存。 前言 我們知道,由于 PHP 沒有多線程模型,所以 swoole 更多的使用多進(jìn)程模型,因此代碼相對(duì)來說更加簡(jiǎn)潔,減少了各種線程鎖的阻塞與同步,但是也帶來了新的問題...

    diabloneo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<