国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位

這篇具有很好參考價(jià)值的文章主要介紹了RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

可以看一下這篇我寫(xiě)的博客,了解一下大概:?

RingBuffer 環(huán)形緩沖區(qū)----鏡像指示位_呵呵噠( ̄▽?zhuān)?"的博客-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/132340883?spm=1001.2014.3001.5501

【回顧】緩沖區(qū)變滿(mǎn)在環(huán)形緩沖區(qū)(ring buffer)中會(huì)實(shí)際發(fā)生,一般會(huì)有兩種處理策略:

??????????① 覆蓋老數(shù)據(jù)

??????????② 拋出“異?!?/p>

鏡像指示位:緩沖區(qū)的長(zhǎng)度如果是n,邏輯地址空間則為0至n-1;那么,規(guī)定n至2n-1為鏡像邏輯地址空間。本策略規(guī)定讀寫(xiě)指針的地址空間為0至2n-1,其中低半部分對(duì)應(yīng)于常規(guī)的邏輯地址空間,高半部分對(duì)應(yīng)于鏡像邏輯地址空間。當(dāng)指針值大于等于2n時(shí),使其折返(wrapped)到ptr-2n。使用一位表示寫(xiě)指針或讀指針是否進(jìn)入了虛擬的鏡像存儲(chǔ)區(qū):置位表示進(jìn)入,不置位表示沒(méi)進(jìn)入還在基本存儲(chǔ)區(qū)。

? ? ? ? 在讀寫(xiě)指針的值相同情況下,如果二者的指示位相同,說(shuō)明緩沖區(qū)為空;如果二者的指示位不同,說(shuō)明緩沖區(qū)為滿(mǎn)。這種方法優(yōu)點(diǎn)是測(cè)試緩沖區(qū)滿(mǎn)/空很簡(jiǎn)單;不需要做取余數(shù)操作;讀寫(xiě)線(xiàn)程可以分別設(shè)計(jì)專(zhuān)用算法策略,能實(shí)現(xiàn)精致的并發(fā)控制。缺點(diǎn)是讀寫(xiě)指針各需要額外的一位作為指示位。

? ? ? ? 如果緩沖區(qū)長(zhǎng)度是2的冪,則本方法可以省略鏡像指示位。如果讀寫(xiě)指針的值相等,則緩沖區(qū)為空;如果讀寫(xiě)指針相差n,則緩沖區(qū)為滿(mǎn),這可以用條件表達(dá)式(寫(xiě)指針==(讀指針異或緩沖區(qū)長(zhǎng)度))來(lái)判斷。

----(來(lái)自百度百科)

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

一、基本步驟

1.數(shù)據(jù)結(jié)構(gòu)

typedef struct ringbuffer
{
    uint8 *buffer_ptr;
    uint16 read_mirror : 1;
    uint16 read_index : 15;
    uint16 write_mirror : 1;
    uint16 write_index : 15;
    /* as we use msb of index as mirror bit, the size should be signed and
     * could only be positive. */
    uint16 size;
}ringbuff;

?2.緩沖區(qū)初始化

// 緩沖區(qū)初始化 
void rb_init(ringbuff *rb,uint8 *pool,uint16 size){
    /* initialize read and write index */
    rb->read_mirror = rb->read_index = 0;
    rb->write_mirror = rb->write_index = 0;

    /* set buffer pool and size */
    rb->buffer_ptr = pool;
    rb->size = DATA_ALIGN_DOWN(size, DATA_ALIGN_SIZE);
}

?3.創(chuàng)建一個(gè)ringbuffer

// 創(chuàng)建一個(gè)ringbuff
ringbuff* rb_create(uint16_t size) {
    ringbuff *rb;
    uint8_t *pool;

    size = DATA_ALIGN_DOWN(size, DATA_ALIGN_SIZE);// 大小做字節(jié)對(duì)齊

    rb = (ringbuff *)malloc(sizeof(ringbuff));// 申請(qǐng)內(nèi)存
    if (rb == NULL)
        goto exit;

    pool = (uint8_t *)malloc(size);// 申請(qǐng)數(shù)據(jù)緩沖區(qū)內(nèi)存
    if (pool == NULL) {
        free(rb);
        rb = NULL;
        goto exit;
    }
    rb_init(rb, pool, size);// 初始化 ringbuff

exit:
    return rb;
}

?4.銷(xiāo)毀環(huán)形緩沖區(qū)

// 摧毀 ringbuff
void rb_destroy(ringbuff *rb) {   
    cout<<"銷(xiāo)毀ringbuff~"<<endl;    
    free(rb->buffer_ptr);
    free(rb);// 釋放申請(qǐng)的內(nèi)存
}

二、緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)

5.?緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)

舉個(gè)例子:(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù))

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖1:當(dāng)環(huán)形緩沖區(qū)為空時(shí),讀索引和寫(xiě)索引指向相同的位置(這里初始化為0);

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖2:寫(xiě)操作:想往(rb->buffer_size = 8)緩沖區(qū)中寫(xiě)入15個(gè)元素:123456789ABCDEF,但寫(xiě)入的數(shù)據(jù)長(zhǎng)度(length)超過(guò)緩沖區(qū)空閑長(zhǎng)度(space_length)了。解決方法:RT-Thread(覆蓋老數(shù)據(jù)策略)就是只截取后8位數(shù)據(jù)放入緩沖區(qū)。

可知length=15,space_length=8,滿(mǎn)足length > space_length,讓ptr = &ptr[length - rb->buffer_size]

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖3:由圖2的操作可以得到以上的環(huán)形緩沖區(qū)的數(shù)據(jù)內(nèi)容分布

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖4:讀操作,讀取緩沖區(qū)4個(gè)元素:89AB,修改讀索引

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖5:寫(xiě)操作,寫(xiě)入緩沖區(qū)4個(gè)元素:1234,修改寫(xiě)索引

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

?圖6:讀操作,讀取緩沖區(qū)4個(gè)元素:CDEF,修改讀索引

??① 當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)

/* 緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_put_force(ringbuff *rb,const uint8 *ptr,uint16 length);
// 強(qiáng)制往 ringbuff 寫(xiě)入數(shù)據(jù)
uint16 rb_put_force(ringbuff *rb,const uint8 *ptr,uint16 length) {
    uint16 space_length = 0;

    space_length = rb_space_len(rb);
    // cout<<"ptr: "<<ptr<<endl;
    // cout<<"space_length: "<<space_length<<endl;
    // cout<<"length: "<<length<<endl;
    if (length > space_length) { 
        ptr = &ptr[length - rb->size];
        length = rb->size;
    }
    // cout<<"ptr: "<<ptr<<endl;
    // cout<<"length: "<<length<<endl;

    if (rb->size - rb->write_index > length)
    {
        // cout<<"lailailailai"<<endl;
        /* read_index - write_index = empty space */
        memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->write_index += length;

        if (length > space_length)
            rb->read_index = rb->write_index;

        return length;
    }

    memcpy(&rb->buffer_ptr[rb->write_index],
           &ptr[0],
           rb->size - rb->write_index);

    memcpy(&rb->buffer_ptr[0],
           &ptr[rb->size - rb->write_index],
           length - (rb->size - rb->write_index));

    /* we are going into the other side of the mirror */
    rb->write_mirror = ~rb->write_mirror;
    rb->write_index = length - (rb->size - rb->write_index);

    if (length > space_length)
    {
        rb->read_mirror = ~rb->read_mirror;
        rb->read_index = rb->write_index;
    }

    return length;
}

??②?當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)

/* 緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_put(ringbuff *rb,const uint8 *ptr,uint16 length);
// 往 ringbuff 寫(xiě)入數(shù)據(jù)
uint16 rb_put(ringbuff *rb,const uint8 *ptr,uint16 length) {
    uint16 size = 0;

    /* whether has enough space */
    size = rb_space_len(rb);// 獲取 ring_buff 中可用空間的大小

    /* no space */
    if (size == 0)
        return 0;// 如果空間不夠 直接返回

    /* drop some data */
    if (size < length) // 如果緩存區(qū)的空間不夠保存這一次數(shù)據(jù), 則把能夠?qū)懭氲倪@一部分?jǐn)?shù)據(jù)寫(xiě)進(jìn)去
        length = size;
	/* One-time write */
    if (rb->size - rb->write_index > length)
    {
        /* read_index - write_index = empty space */
        memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->write_index += length;
        return length;// 返回寫(xiě)入數(shù)據(jù)的長(zhǎng)度
    }
	/* two-time write */
    memcpy(&rb->buffer_ptr[rb->write_index],
           &ptr[0],
           rb->size - rb->write_index);
    memcpy(&rb->buffer_ptr[0],
           &ptr[rb->size - rb->write_index],
           length - (rb->size - rb->write_index));

    /* we are going into the other side of the mirror */
    rb->write_mirror = ~rb->write_mirror;
    rb->write_index = length - (rb->size - rb->write_index);

    return length;
}

6.?緩沖區(qū)中獲取指定長(zhǎng)度的數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度)

/* 緩沖區(qū)中獲取指定長(zhǎng)度的數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度) */
uint16 rb_get(ringbuff *rb,uint8 *ptr,uint16 length);
// 從 ringbuff 獲取數(shù)據(jù)
uint16 rb_get(ringbuff *rb,uint8 *ptr,uint16 length) {
    uint16 size = 0;

    /* The length of the existing data in the buffer */
    size = rb_data_len(rb);

    /* no data */
    if (size == 0)
        return 0;

    /* less data */
    if (size < length)
        length = size;
    
    cout<<"size: "<<size<<" < "<<"length: " << length<<(size < length)<<endl;

    if (rb->size - rb->read_index > length)
    {
        /* copy all of data */
        memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->read_index += length;
        return length;
    }

    memcpy(&ptr[0],
           &rb->buffer_ptr[rb->read_index],
           rb->size - rb->read_index);
    memcpy(&ptr[rb->size - rb->read_index],
           &rb->buffer_ptr[0],
           length - (rb->size - rb->read_index));

    /* we are going into the other side of the mirror */
    rb->read_mirror = ~rb->read_mirror;
    rb->read_index = length - (rb->size - rb->read_index);

    return length;
}

7.測(cè)試和打印

void readprint(ringbuff* rb,uint8 buff[]) {
    cout<<"讀取數(shù)據(jù):";
    int i = 0;
    while(buff[i]!='\0') {
        cout<<buff[i++];
    }
    print(rb);
}

void writeprint(ringbuff* rb){
    for(int i=0;i<rb->size;i++){
        cout<<rb->buffer_ptr[i];
    }
    print(rb);
}

void test01() {
    ringbuff* rb = rb_create(9);

    const uint8 p[] = "123456789ABCDEF";
    uint32_t len = sizeof(p) / sizeof(char);
    
    cout<<"寫(xiě)入數(shù)據(jù):"<<p<<endl;
    // rb_put(rb,p,len-1);
    rb_put_force(rb,p,len-1); 
    writeprint(rb);                       // 89ABCDEF

    uint8 saveBuff[20] = "";
    rb_get(rb,saveBuff,4);   // 89AB
    readprint(rb,saveBuff);
    
    const uint8 p1[] = "1234";
    cout<<"寫(xiě)入數(shù)據(jù):"<<p1<<endl;
    rb_put_force(rb,p1,4);    // 1234CDEF
    writeprint(rb);

    memset(saveBuff,0,20);
    rb_get(rb,saveBuff,4);   // CDEF
    
    cout<<"讀取數(shù)據(jù):";
    readprint(rb,saveBuff);

    // 銷(xiāo)毀ringbuff
    rb_destroy(rb);
}
寫(xiě)入數(shù)據(jù):123456789ABCDEF
89ABCDEF
rb->write_index: 0
rb->read_index: 0
rb->write_mirror: 1
rb->read_mirror: 0
rb_data_len: 8
rb_space_len: 0

size: 8 < length: 40
讀取數(shù)據(jù):89AB
rb->write_index: 0
rb->read_index: 4
rb->write_mirror: 1
rb->read_mirror: 0
rb_data_len: 4
rb_space_len: 4

寫(xiě)入數(shù)據(jù):1234
1234CDEF
rb->write_index: 4
rb->read_index: 4
rb->write_mirror: 1
rb->read_mirror: 0
rb_data_len: 8
rb_space_len: 0

size: 8 < length: 40
讀取數(shù)據(jù):讀取數(shù)據(jù):CDEF
rb->write_index: 4
rb->read_index: 0
rb->write_mirror: 1
rb->read_mirror: 1
rb_data_len: 4
rb_space_len: 4

銷(xiāo)毀ringbuff~

三、緩沖區(qū)中填充一個(gè)數(shù)據(jù)

5.?緩沖區(qū)中填充一個(gè)數(shù)據(jù)

舉個(gè)例子:(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù))

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖1:依次存入1、2、3、4、5、6、7、8、A、B、C、D、E、F這些字符,直到緩沖區(qū)為滿(mǎn)

RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位,ringbuffer,鏡像指示位,RT-Thread

圖2:依次讀出單個(gè)字符: 8、9、A、B

??① 當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)

/* 緩沖區(qū)中填充一個(gè)數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_putchar_force(ringbuff *rb, const uint8 ch);
// 往 ringbuff 強(qiáng)制寫(xiě)入一個(gè)字符
uint16 rb_putchar_force(ringbuff *rb, const uint8 ch) {
    enum rb_state old_state = rb_status(rb);// 獲取狀態(tài)
    rb->buffer_ptr[rb->write_index] = ch;// 寫(xiě)入數(shù)據(jù)
    /* flip mirror */
    if (rb->write_index == rb->size-1) {// 檢查當(dāng)前鏡像是不是滿(mǎn)了
        rb->write_mirror = ~rb->write_mirror; // 翻轉(zhuǎn)寫(xiě)鏡像
        rb->write_index = 0;// 翻轉(zhuǎn)之后設(shè)置下標(biāo)為 0
        if (old_state == RINGBUFFER_FULL) {// 如果 ringbuff 的狀態(tài)是滿(mǎn)
            rb->read_mirror = ~rb->read_mirror; // 翻轉(zhuǎn)讀鏡像
            rb->read_index = rb->write_index; // 設(shè)置讀下標(biāo)和寫(xiě)下標(biāo)一致
        }
    }else{
        rb->write_index++; // 寫(xiě)下標(biāo)加1
        if (old_state == RINGBUFFER_FULL)
            rb->read_index = rb->write_index;// 如果滿(mǎn),設(shè)置讀下標(biāo)等于寫(xiě)下標(biāo)
    }
    return 1; // 寫(xiě)入一個(gè)字符,返回1
}

??② 當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)

/* 緩沖區(qū)中填充一個(gè)數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_putchar(ringbuff *rb, const uint8 ch);
// 往 ringbuff 中寫(xiě)入一個(gè)字符
uint16 rb_putchar(ringbuff *rb, const uint8 ch) {
    /* whether has enough space */
    if (!rb_space_len(rb)) // 沒(méi)有足夠的空間就直接返回了
        return 0;
    rb->buffer_ptr[rb->write_index] = ch;// 把這個(gè)字符寫(xiě)入到緩沖區(qū)的指定位置
    /* flip mirror */
    if (rb->write_index == rb->size-1) {// 檢查寫(xiě)入這個(gè)字符后,當(dāng)前鏡像是否寫(xiě)滿(mǎn)
        rb->write_mirror = ~rb->write_mirror;// 翻轉(zhuǎn)鏡像
        rb->write_index = 0;// 設(shè)置下標(biāo)為0
    }else{
        rb->write_index++; // 下標(biāo)加1
    }
    return 1;// 寫(xiě)入一個(gè)字符,返回 1
}

6.?緩沖區(qū)中獲取一個(gè)數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度)

/* 緩沖區(qū)中獲取一個(gè)數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度) */
uint16 rb_getchar(ringbuff *rb, uint8 *ch);
// 從ringbuff 獲取一個(gè)字符
uint16 rb_getchar(ringbuff *rb,uint8 *ch) {
    /* ringbuffer is empty */
    if (!rb_data_len(rb)) // 檢查 ringbuff 是否為空
        return 0;
    /* put character */
    *ch = rb->buffer_ptr[rb->read_index];// 獲取當(dāng)前讀下標(biāo)的數(shù)據(jù)
    if (rb->read_index == rb->size-1) {// 如果當(dāng)前鏡像滿(mǎn)了
        rb->read_mirror = ~rb->read_mirror;// 翻轉(zhuǎn)鏡像
        rb->read_index = 0; // 設(shè)置讀數(shù)據(jù)的下標(biāo)為0
    } else {
        rb->read_index++; // 下標(biāo)加1
    }

    return 1;// 讀取一個(gè)字節(jié),返回1
}

7.測(cè)試和打印

#include "rb.h"
#include "rb.cpp"
void print(ringbuff *rb) {
    cout<<endl;
    cout<<"rb->write_index: "<<rb->write_index<<endl;
    cout<<"rb->read_index: "<<rb->read_index<<endl;
    cout<<"rb->write_mirror: "<<rb->write_mirror<<endl;
    cout<<"rb->read_mirror: "<<rb->read_mirror<<endl;
    cout<<"rb_data_len: "<<rb_data_len(rb)<<endl;
    cout<<"rb_space_len: "<<rb_space_len(rb)<<endl;
    cout<<endl;
}

void writeprint(ringbuff* rb){
    for(int i=0;i<rb->size;i++){
        cout<<rb->buffer_ptr[i];
    }
    print(rb);
}

void test02() {
    ringbuff* rb = rb_create(9);
    cout<<"rb->size: "<<rb->size<<endl;
    const uint8 p[] = "123456789ABCDEF";
    uint32_t len = sizeof(p) / sizeof(char);
    // cout<<len<<endl;
    cout<<"寫(xiě)入數(shù)據(jù):"<<p<<endl;
    for(int i=0;i<len-1;i++) {
        // rb_putchar(rb,p[i]); 
        rb_putchar_force(rb,p[i]); 
    }
    writeprint(rb); // 9ABCDEF8                      

    uint8 singlechar = ' ';
    for(int i=0;i<4;i++) {
        rb_getchar(rb,&singlechar);
        cout<<"讀單個(gè)字符: "<<singlechar<<endl;
    }
    print(rb);

    // 銷(xiāo)毀ringbuff
    rb_destroy(rb);
}
rb->size: 8
寫(xiě)入數(shù)據(jù):123456789ABCDEF
9ABCDEF8
rb->write_index: 7
rb->read_index: 7
rb->write_mirror: 1
rb->read_mirror: 0
rb_data_len: 8
rb_space_len: 0

讀單個(gè)字符: 8
讀單個(gè)字符: 9
讀單個(gè)字符: A
讀單個(gè)字符: B

rb->write_index: 7
rb->read_index: 3
rb->write_mirror: 1
rb->read_mirror: 1
rb_data_len: 4
rb_space_len: 4

銷(xiāo)毀ringbuff~

四、RT-Thread??小結(jié)

來(lái)自此文總結(jié):ring buffer,一篇文章講透它? - 知乎 (zhihu.com)

?? 在多線(xiàn)程中,對(duì)同一個(gè)環(huán)形緩沖區(qū)進(jìn)行讀寫(xiě)操作時(shí),需要加上鎖,不然存在訪(fǎng)問(wèn)不安全問(wèn)題;

?? 當(dāng)只有一個(gè)讀線(xiàn)程和一個(gè)寫(xiě)線(xiàn)程時(shí),用rb_put和rb_get進(jìn)行讀寫(xiě)操作緩沖區(qū)是線(xiàn)程安全的,無(wú)需加鎖;但是rb_put_force不行,因?yàn)槠淇赡軐?duì)讀寫(xiě)索引都進(jìn)行操作的場(chǎng)景,這個(gè)時(shí)候再進(jìn)行rb_get讀操作,就是不安全訪(fǎng)問(wèn);

?? 讀寫(xiě)指針已經(jīng)在讀寫(xiě)(rb_get和rb_put)過(guò)程中轉(zhuǎn)換為了讀寫(xiě)索引。所以read_index(讀索引)和write_index(寫(xiě)索引)可以直接用來(lái)操作緩沖區(qū),無(wú)需轉(zhuǎn)換;

?? read_index 和write_index 的大小區(qū)間為[0,n?1],n為緩沖區(qū)大?。?/p>

?? RT-Thread的環(huán)形緩沖區(qū)不需要buffer大小為2的冪。

五、完整代碼

rb.h

#ifndef RB
#define RB

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;

typedef unsigned char           uint8;
typedef signed char             int8;
typedef unsigned short          wchar;
typedef unsigned short int      uint16;
typedef signed short int        int16;
typedef unsigned int            uint32;
typedef signed int              int32;

typedef signed char 			int8_t;
typedef signed short int 		int16_t;
typedef signed int 				int32_t;
typedef unsigned char 			uint8_t;
typedef unsigned short int 		uint16_t;
typedef unsigned int 			uint32_t;

/*
 * Return the down number of aligned at specified width. RT_ALIGN_DOWN(13, 4)
 * would return 12.*/
#define DATA_ALIGN_DOWN(size, align)      ((size) & ~((align) - 1))
/* DATA_ALIGN_SIZE*/
#define DATA_ALIGN_SIZE	4

/* ring buffer */
typedef struct ringbuffer
{
    uint8 *buffer_ptr;
    uint16 read_mirror : 1;
    uint16 read_index : 15;
    uint16 write_mirror : 1;
    uint16 write_index : 15;
    /* as we use msb of index as mirror bit, the size should be signed and
     * could only be positive. */
    uint16 size;
}ringbuff;

/* 緩沖區(qū)初始化 */
void rb_init(ringbuff *rb,uint8 *pool,uint16 size);
/* 創(chuàng)建一個(gè)ringbuff */
ringbuff* rb_create(uint16_t size);
/* 銷(xiāo)毀一個(gè)ringbuff */
void rb_destroy(ringbuff *rb);

/* 緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_put(ringbuff *rb,const uint8 *ptr,uint16 length);
/* 緩沖區(qū)中填充指定數(shù)據(jù)長(zhǎng)度的數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_put_force(ringbuff *rb,const uint8 *ptr,uint16 length);
/* 緩沖區(qū)中填充一個(gè)數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事不覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_putchar(ringbuff *rb, const uint8 ch);
/* 緩沖區(qū)中填充一個(gè)數(shù)據(jù)(當(dāng)緩沖區(qū)空間小于待寫(xiě)入的數(shù)據(jù)長(zhǎng)度事覆蓋緩沖區(qū)原有數(shù)據(jù)) */
uint16 rb_putchar_force(ringbuff *rb, const uint8 ch);

/* 緩沖區(qū)中獲取指定長(zhǎng)度的數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度) */
uint16 rb_get(ringbuff *rb,uint8 *ptr,uint16 length);
/* 緩沖區(qū)中獲取一個(gè)數(shù)據(jù)(返回實(shí)際獲取數(shù)據(jù)的長(zhǎng)度) */
uint16 rb_getchar(ringbuff *rb, uint8 *ch);

/* 獲取 ringbuff 中數(shù)據(jù)的長(zhǎng)度 */
uint16 rb_data_len(ringbuff *rb);

/** return the size of empty space in rb */
#define rb_space_len(rb) ((rb)->size - rb_data_len(rb))

#endif /* RB */

rb.cpp

#include "rb.h"
enum rb_state
{
    RINGBUFFER_EMPTY,
    RINGBUFFER_FULL,
    RINGBUFFER_HALFFULL, /* half full is neither full nor empty */
};
// 獲取 ringbuff 的狀態(tài)
enum rb_state rb_status(ringbuff *rb) {
    if (rb->read_index == rb->write_index)
    {
        if (rb->read_mirror == rb->write_mirror)
            return RINGBUFFER_EMPTY;
        else
            return RINGBUFFER_FULL;
    }
    return RINGBUFFER_HALFFULL;
}

// 獲取 ringbuff 中數(shù)據(jù)的長(zhǎng)度
uint16 rb_data_len(ringbuff *rb) {
    switch (rb_status(rb)) {
        case RINGBUFFER_EMPTY:
            return 0;//空就返回 0 
        case RINGBUFFER_FULL:
            return rb->size;// 滿(mǎn)就返回緩沖區(qū)的大小
        case RINGBUFFER_HALFFULL:// 半滿(mǎn)
        default:
            if (rb->write_index > rb->read_index) // 如果在同一鏡像
                return rb->write_index - rb->read_index; // 返回下標(biāo)差
            else
                return rb->size - (rb->read_index - rb->write_index); // 如果不在同一鏡像,通過(guò)計(jì)算獲取數(shù)據(jù)的長(zhǎng)度
    };
}

// 緩沖區(qū)初始化 
void rb_init(ringbuff *rb,uint8 *pool,uint16 size){
    /* initialize read and write index */
    rb->read_mirror = rb->read_index = 0;
    rb->write_mirror = rb->write_index = 0;

    /* set buffer pool and size */
    rb->buffer_ptr = pool;
    rb->size = DATA_ALIGN_DOWN(size, DATA_ALIGN_SIZE);
}

// 創(chuàng)建一個(gè)ringbuff
ringbuff* rb_create(uint16_t size) {
    ringbuff *rb;
    uint8_t *pool;

    size = DATA_ALIGN_DOWN(size, DATA_ALIGN_SIZE);// 大小做字節(jié)對(duì)齊

    rb = (ringbuff *)malloc(sizeof(ringbuff));// 申請(qǐng)內(nèi)存
    if (rb == NULL)
        goto exit;

    pool = (uint8_t *)malloc(size);// 申請(qǐng)數(shù)據(jù)緩沖區(qū)內(nèi)存
    if (pool == NULL) {
        free(rb);
        rb = NULL;
        goto exit;
    }
    rb_init(rb, pool, size);// 初始化 ringbuff

exit:
    return rb;
}

// 往 ringbuff 寫(xiě)入數(shù)據(jù)
uint16 rb_put(ringbuff *rb,const uint8 *ptr,uint16 length) {
    uint16 size = 0;

    /* whether has enough space */
    size = rb_space_len(rb);// 獲取 ring_buff 中可用空間的大小

    /* no space */
    if (size == 0)
        return 0;// 如果空間不夠 直接返回

    /* drop some data */
    if (size < length) // 如果緩存區(qū)的空間不夠保存這一次數(shù)據(jù), 則把能夠?qū)懭氲倪@一部分?jǐn)?shù)據(jù)寫(xiě)進(jìn)去
        length = size;
	/* One-time write */
    if (rb->size - rb->write_index > length)
    {
        /* read_index - write_index = empty space */
        memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->write_index += length;
        return length;// 返回寫(xiě)入數(shù)據(jù)的長(zhǎng)度
    }
	/* two-time write */
    memcpy(&rb->buffer_ptr[rb->write_index],
           &ptr[0],
           rb->size - rb->write_index);
    memcpy(&rb->buffer_ptr[0],
           &ptr[rb->size - rb->write_index],
           length - (rb->size - rb->write_index));

    /* we are going into the other side of the mirror */
    rb->write_mirror = ~rb->write_mirror;
    rb->write_index = length - (rb->size - rb->write_index);

    return length;
}

// 強(qiáng)制往 ringbuff 寫(xiě)入數(shù)據(jù)
uint16 rb_put_force(ringbuff *rb,const uint8 *ptr,uint16 length) {
    uint16 space_length = 0;

    space_length = rb_space_len(rb);
    // cout<<"ptr: "<<ptr<<endl;
    // cout<<"space_length: "<<space_length<<endl;
    // cout<<"length: "<<length<<endl;
    if (length > space_length) { 
        ptr = &ptr[length - rb->size];
        length = rb->size;
    }
    // cout<<"ptr: "<<ptr<<endl;
    // cout<<"length: "<<length<<endl;

    if (rb->size - rb->write_index > length)
    {
        // cout<<"lailailailai"<<endl;
        /* read_index - write_index = empty space */
        memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->write_index += length;

        if (length > space_length)
            rb->read_index = rb->write_index;

        return length;
    }

    memcpy(&rb->buffer_ptr[rb->write_index],
           &ptr[0],
           rb->size - rb->write_index);

    memcpy(&rb->buffer_ptr[0],
           &ptr[rb->size - rb->write_index],
           length - (rb->size - rb->write_index));

    /* we are going into the other side of the mirror */
    rb->write_mirror = ~rb->write_mirror;
    rb->write_index = length - (rb->size - rb->write_index);

    if (length > space_length)
    {
        rb->read_mirror = ~rb->read_mirror;
        rb->read_index = rb->write_index;
    }

    return length;
}

// 從 ringbuff 獲取數(shù)據(jù)
uint16 rb_get(ringbuff *rb,uint8 *ptr,uint16 length) {
    uint16 size = 0;

    /* The length of the existing data in the buffer */
    size = rb_data_len(rb);

    /* no data */
    if (size == 0)
        return 0;

    /* less data */
    if (size < length)
        length = size;
    
    cout<<"size: "<<size<<" < "<<"length: " << length<<(size < length)<<endl;

    if (rb->size - rb->read_index > length)
    {
        /* copy all of data */
        memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
        /* this should not cause overflow because there is enough space for
         * length of data in current mirror */
        rb->read_index += length;
        return length;
    }

    memcpy(&ptr[0],
           &rb->buffer_ptr[rb->read_index],
           rb->size - rb->read_index);
    memcpy(&ptr[rb->size - rb->read_index],
           &rb->buffer_ptr[0],
           length - (rb->size - rb->read_index));

    /* we are going into the other side of the mirror */
    rb->read_mirror = ~rb->read_mirror;
    rb->read_index = length - (rb->size - rb->read_index);

    return length;
}

// 往 ringbuff 中寫(xiě)入一個(gè)字符
uint16 rb_putchar(ringbuff *rb, const uint8 ch) {
    /* whether has enough space */
    if (!rb_space_len(rb)) // 沒(méi)有足夠的空間就直接返回了
        return 0;
    rb->buffer_ptr[rb->write_index] = ch;// 把這個(gè)字符寫(xiě)入到緩沖區(qū)的指定位置
    /* flip mirror */
    if (rb->write_index == rb->size-1) {// 檢查寫(xiě)入這個(gè)字符后,當(dāng)前鏡像是否寫(xiě)滿(mǎn)
        rb->write_mirror = ~rb->write_mirror;// 翻轉(zhuǎn)鏡像
        rb->write_index = 0;// 設(shè)置下標(biāo)為0
    }else{
        rb->write_index++; // 下標(biāo)加1
    }
    return 1;// 寫(xiě)入一個(gè)字符,返回 1
}

// 往 ringbuff 強(qiáng)制寫(xiě)入一個(gè)字符
uint16 rb_putchar_force(ringbuff *rb, const uint8 ch) {
    enum rb_state old_state = rb_status(rb);// 獲取狀態(tài)
    rb->buffer_ptr[rb->write_index] = ch;// 寫(xiě)入數(shù)據(jù)
    /* flip mirror */
    if (rb->write_index == rb->size-1) {// 檢查當(dāng)前鏡像是不是滿(mǎn)了
        rb->write_mirror = ~rb->write_mirror; // 翻轉(zhuǎn)寫(xiě)鏡像
        rb->write_index = 0;// 翻轉(zhuǎn)之后設(shè)置下標(biāo)為 0
        if (old_state == RINGBUFFER_FULL) {// 如果 ringbuff 的狀態(tài)是滿(mǎn)
            rb->read_mirror = ~rb->read_mirror; // 翻轉(zhuǎn)讀鏡像
            rb->read_index = rb->write_index; // 設(shè)置讀下標(biāo)和寫(xiě)下標(biāo)一致
        }
    }else{
        rb->write_index++; // 寫(xiě)下標(biāo)加1
        if (old_state == RINGBUFFER_FULL)
            rb->read_index = rb->write_index;// 如果滿(mǎn),設(shè)置讀下標(biāo)等于寫(xiě)下標(biāo)
    }
    return 1; // 寫(xiě)入一個(gè)字符,返回1
}

// 從ringbuff 獲取一個(gè)字符
uint16 rb_getchar(ringbuff *rb,uint8 *ch) {
    /* ringbuffer is empty */
    if (!rb_data_len(rb)) // 檢查 ringbuff 是否為空
        return 0;
    /* put character */
    *ch = rb->buffer_ptr[rb->read_index];// 獲取當(dāng)前讀下標(biāo)的數(shù)據(jù)
    if (rb->read_index == rb->size-1) {// 如果當(dāng)前鏡像滿(mǎn)了
        rb->read_mirror = ~rb->read_mirror;// 翻轉(zhuǎn)鏡像
        rb->read_index = 0; // 設(shè)置讀數(shù)據(jù)的下標(biāo)為0
    } else {
        rb->read_index++; // 下標(biāo)加1
    }

    return 1;// 讀取一個(gè)字節(jié),返回1
}

// 摧毀 ringbuff
void rb_destroy(ringbuff *rb) {   
    cout<<"銷(xiāo)毀ringbuff~"<<endl;    
    free(rb->buffer_ptr);
    free(rb);// 釋放申請(qǐng)的內(nèi)存
}

test.cpp文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-660711.html

#include "rb.h"
#include "rb.cpp"
void print(ringbuff *rb) {
    cout<<endl;
    cout<<"rb->write_index: "<<rb->write_index<<endl;
    cout<<"rb->read_index: "<<rb->read_index<<endl;
    cout<<"rb->write_mirror: "<<rb->write_mirror<<endl;
    cout<<"rb->read_mirror: "<<rb->read_mirror<<endl;
    cout<<"rb_data_len: "<<rb_data_len(rb)<<endl;
    cout<<"rb_space_len: "<<rb_space_len(rb)<<endl;
    cout<<endl;
}

void readprint(ringbuff* rb,uint8 buff[]) {
    cout<<"讀取數(shù)據(jù):";
    int i = 0;
    while(buff[i]!='\0') {
        cout<<buff[i++];
    }
    print(rb);
}

void writeprint(ringbuff* rb){
    for(int i=0;i<rb->size;i++){
        cout<<rb->buffer_ptr[i];
    }
    print(rb);
}

void test01() {
    ringbuff* rb = rb_create(9);

    const uint8 p[] = "123456789ABCDEF";
    uint32_t len = sizeof(p) / sizeof(char);
    
    cout<<"寫(xiě)入數(shù)據(jù):"<<p<<endl;
    // rb_put(rb,p,len-1);
    rb_put_force(rb,p,len-1); 
    writeprint(rb);                       // 89ABCDEF

    uint8 saveBuff[20] = "";
    rb_get(rb,saveBuff,4);   // 89AB
    readprint(rb,saveBuff);
    
    const uint8 p1[] = "1234";
    cout<<"寫(xiě)入數(shù)據(jù):"<<p1<<endl;
    rb_put_force(rb,p1,4);    // 1234CDEF
    writeprint(rb);

    memset(saveBuff,0,20);
    rb_get(rb,saveBuff,4);   // CDEF
    
    cout<<"讀取數(shù)據(jù):";
    readprint(rb,saveBuff);

    // 銷(xiāo)毀ringbuff
    rb_destroy(rb);
}

void test02() {
    ringbuff* rb = rb_create(9);
    cout<<"rb->size: "<<rb->size<<endl;
    const uint8 p[] = "123456789ABCDEF";
    uint32_t len = sizeof(p) / sizeof(char);
    // cout<<len<<endl;
    cout<<"寫(xiě)入數(shù)據(jù):"<<p<<endl;
    for(int i=0;i<len-1;i++) {
        // rb_putchar(rb,p[i]); 
        rb_putchar_force(rb,p[i]); 
    }
    writeprint(rb); // 9ABCDEF8                      

    uint8 singlechar = ' ';
    for(int i=0;i<4;i++) {
        rb_getchar(rb,&singlechar);
        cout<<"讀單個(gè)字符: "<<singlechar<<endl;
    }
    print(rb);

    // 銷(xiāo)毀ringbuff
    rb_destroy(rb);
}
int main() {
    // test01();
    test02();
    return 0;
}

到了這里,關(guān)于RT-Thread 的環(huán)形緩沖區(qū) ---- 鏡像指示位的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 理解緩沖區(qū)

    理解緩沖區(qū)

    對(duì)于這樣的代碼,首先可以肯定的是 printf 語(yǔ)句先于 sleep 執(zhí)行,既然如此那么就應(yīng)該是先打印語(yǔ)句然后進(jìn)行休眠,下面看看結(jié)果: 但這里卻是先休眠以后再打印語(yǔ)句,這是因?yàn)榇嬖谝粋€(gè)叫緩沖區(qū)的東西,當(dāng)我們要向外設(shè)寫(xiě)入數(shù)據(jù)(讓顯示器顯示就是向顯示器寫(xiě)入數(shù)據(jù))時(shí)會(huì)將

    2023年04月25日
    瀏覽(22)
  • Redis 緩沖區(qū)

    Redis 緩沖區(qū)

    緩沖區(qū)的應(yīng)用場(chǎng)景 : 客戶(hù)端與服務(wù)器端的通信時(shí),暫存客戶(hù)端發(fā)送的命令數(shù)據(jù),或暫存服務(wù)器端返給客戶(hù)端的數(shù)據(jù)結(jié)果 主從節(jié)點(diǎn)間進(jìn)行數(shù)據(jù)同步時(shí),暫存主節(jié)點(diǎn)接收的寫(xiě)命令和數(shù)據(jù) 緩沖區(qū) : 避免客戶(hù)端和服務(wù)器端的請(qǐng)求發(fā)送和處理速度不匹配 服務(wù)器給每個(gè)連接的客戶(hù)端都準(zhǔn)

    2024年02月07日
    瀏覽(21)
  • 8.緩沖區(qū)管理

    8.緩沖區(qū)管理

    雙緩沖區(qū):TC+M 假設(shè)初始狀態(tài)緩沖區(qū)1滿(mǎn),緩沖區(qū)2空,工作區(qū)為空。 剛開(kāi)始緩沖區(qū)2為空,所以設(shè)備可以向緩沖區(qū)2中沖入數(shù)據(jù)耗時(shí)T,另一方面剛開(kāi)始緩沖區(qū)1中是滿(mǎn)的,所以剛開(kāi)始就可以把緩沖區(qū)1中的數(shù)據(jù)傳送到工作區(qū)中,M時(shí)刻工作區(qū)被充滿(mǎn),CPU就開(kāi)始處理數(shù)據(jù)耗時(shí)C,處理完

    2024年02月11日
    瀏覽(26)
  • 【Linux】理解緩沖區(qū)

    【Linux】理解緩沖區(qū)

    我們發(fā)現(xiàn) printf 和 fwrite (庫(kù)函數(shù))都輸出了2次,而 write 只輸出了一次(系統(tǒng)調(diào)用)。為什么呢?肯定和fork有關(guān)! C接口的函數(shù)被打印了兩次系統(tǒng)接口前后只是打印了一次:和fork函數(shù)有關(guān),fork會(huì)創(chuàng)建子進(jìn)程。在創(chuàng)建子進(jìn)程的時(shí)候,數(shù)據(jù)會(huì)被處理成兩份,父子進(jìn)程發(fā)生寫(xiě)時(shí)拷

    2024年01月23日
    瀏覽(19)
  • 【Linux】文件緩沖區(qū)

    【Linux】文件緩沖區(qū)

    提到文件緩沖區(qū)這個(gè)概念我們好像并不陌生,但是我們對(duì)于這個(gè)概念好像又是模糊的存在腦海中,之間我們?cè)诮榻Bc語(yǔ)言文件操作已經(jīng)簡(jiǎn)單的提過(guò)這個(gè)概念,今天我們不妨深入理解什么是文件緩沖區(qū) 通過(guò)自己實(shí)現(xiàn)庫(kù)中的一些文件操作函數(shù)更加深入的理解文件緩沖區(qū) 自定義實(shí)現(xiàn)

    2024年02月10日
    瀏覽(25)
  • C/C++緩沖區(qū)

    什么是緩沖區(qū)? 程序和磁盤(pán)文件之間不能直接交換數(shù)據(jù),必須通過(guò)內(nèi)存中一個(gè)被稱(chēng)為文件緩沖區(qū)的區(qū)域來(lái)中轉(zhuǎn)。ANSIC標(biāo)準(zhǔn)規(guī)定,系統(tǒng)會(huì)自動(dòng)為每個(gè)正在使用的文件在內(nèi)存中開(kāi)辟一個(gè)緩沖區(qū),緩沖區(qū)的大小隨機(jī)器而異。 緩沖區(qū)有什么作用? 假設(shè)我們?cè)诩抑行菹⒖措娨暢粤闶常?/p>

    2024年02月15日
    瀏覽(21)
  • SEED-緩沖區(qū)溢出攻擊

    SEED-緩沖區(qū)溢出攻擊

    實(shí)驗(yàn)環(huán)境:SEED-Ubuntu20.04虛擬機(jī) a) 緩沖區(qū)溢出原理 **緩沖區(qū)溢出攻擊原理:**利用溢出的數(shù)據(jù)改變?cè)闯绦虻目刂屏?,如覆蓋返回地址 b) 分析生成badfile文件的exploit.py程序 Shellcode部分 字節(jié)數(shù)組末尾處填入shellcode c) 編譯目標(biāo)服務(wù)器上具有緩沖區(qū)溢出漏洞的stack.c程序,并將其緩沖

    2024年02月07日
    瀏覽(26)
  • 【linux】重定向+緩沖區(qū)

    【linux】重定向+緩沖區(qū)

    自我名言 : 只有努力,才能追逐夢(mèng)想,只有努力,才不會(huì)欺騙自己。 喜歡的點(diǎn)贊,收藏,關(guān)注一下把! close(1),為什么沒(méi)有打印新建文件fd呢? printf(“%dn”,fd); printf會(huì)把內(nèi)容打印到stdout文件中。 但是close(1)關(guān)閉標(biāo)準(zhǔn)輸出stdout—顯示器,int fd=open();新打開(kāi)的文件fd是1。 st

    2024年02月08日
    瀏覽(22)
  • 【Linux】深入理解緩沖區(qū)

    【Linux】深入理解緩沖區(qū)

    目錄 什么是緩沖區(qū) 為什么要有緩沖區(qū) 緩沖區(qū)刷新策略 緩沖區(qū)在哪里 ?手動(dòng)設(shè)計(jì)一個(gè)用戶(hù)層緩沖區(qū) 緩沖區(qū)本質(zhì)上一塊內(nèi)存區(qū)域,用來(lái)保存臨時(shí)數(shù)據(jù)。 緩沖區(qū)在各種計(jì)算任務(wù)中都廣泛應(yīng)用,包括輸入/輸出操作、網(wǎng)絡(luò)通信、圖像處理、音頻處理等。 這塊內(nèi)存區(qū)域是由 誰(shuí)提供的

    2024年02月15日
    瀏覽(22)
  • Linux之緩沖區(qū)的理解

    Linux之緩沖區(qū)的理解

    目錄 一、問(wèn)題引入 二、緩沖區(qū) 1、什么是緩沖區(qū) 2、刷新策略 3、緩沖區(qū)由誰(shuí)提供 4、重看問(wèn)題 三、緩沖區(qū)的簡(jiǎn)單實(shí)現(xiàn) 我們先來(lái)看看下面的代碼:我們使用了C語(yǔ)言接口和系統(tǒng)調(diào)用接口來(lái)進(jìn)行文件操作。在代碼的最后,我們還使用fork函數(shù)創(chuàng)建了一個(gè)子進(jìn)程。 ?代碼運(yùn)行結(jié)果如

    2024年02月03日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包