一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言環(huán)形隊列的原理和特點

strongerHuang ? 來源:嵌入式Linux ? 作者:寫代碼的籃球球癡 ? 2021-05-11 13:56 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

什么是環(huán)形隊列?

環(huán)形緩沖區(qū)是一個非常典型的數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)符合生產(chǎn)者,消費者模型,可以理解它是一個水坑,生產(chǎn)者不斷的往里面灌水,消費者就不斷的從里面取出水。

那就可能會有人問,既然需要灌水,又需要取出水,為什么還需要開辟一個緩沖區(qū)內(nèi)存空間呢?直接把生產(chǎn)者水管的尾部接到消費者水管的頭部不就好了,這樣可以省空間啊。

答案是不行的,生產(chǎn)者生產(chǎn)水的速度是不知道的,消費者消費水的速度也是不知道的,如果你強制接在一起,因為生產(chǎn)和消費的速度不同,就非常可能存在水管爆炸的情況,你說這樣危險不危險?

音頻系統(tǒng)框架下,alsa就是使用環(huán)形隊列的,在生產(chǎn)者和消費者速度不匹配的時候,就會出現(xiàn)xrun的問題。

環(huán)形隊列的特點

1、數(shù)組構(gòu)造環(huán)形緩沖區(qū)

假設(shè)我們用數(shù)組來構(gòu)造一個環(huán)形緩存區(qū),如下圖

59134ccc-b20d-11eb-bf61-12bb97331649.png

我們需要幾個東西來形容這個環(huán)形緩沖區(qū),一個的讀位置,一個是寫位置,一個是環(huán)形緩沖區(qū)的長度

5928e3fc-b20d-11eb-bf61-12bb97331649.png

從圖片看,我們知道,這個環(huán)形緩沖區(qū)的讀寫位置是指向數(shù)組的首地址的,環(huán)形緩沖區(qū)的長度是 5 。

那如何判斷環(huán)形緩沖區(qū)為空呢?

如果 R == W 就是讀寫位置相同,則這個環(huán)形緩沖區(qū)為空

那如何判斷環(huán)形緩沖區(qū)滿了呢?

如果 (W - R )= Len ,則這個環(huán)形緩沖區(qū)已經(jīng)滿了。

2、向環(huán)形緩沖區(qū)寫入 3個數(shù)據(jù)

寫入 3 個數(shù)據(jù)后,W 的值等于 3 了,R 還是等于 0。

3個企鵝已經(jīng)排列

3、從環(huán)形緩沖區(qū)讀取2個數(shù)據(jù)

讀出兩個數(shù)據(jù)后,R = 2 了,這個時候,W還是等于 3,畢竟沒有再寫過數(shù)據(jù)了。

4、再寫入3個數(shù)據(jù)

如果 W 》 LEN 后,怎么找到最開始的位置的呢?這個就需要進行運算了,W%LEN 的位置就是放入數(shù)據(jù)的位置 ,6%5 = 1。

5、再寫入1個數(shù)據(jù)

這個時候環(huán)形隊列已經(jīng)滿了,要是想再寫入數(shù)據(jù)的話,就不行了,(W - R) = 5 == LEN

代碼實現(xiàn)

/* 實現(xiàn)的最簡單的ringbuff 有更多提升空間,可以留言說明 */

#include “stdio.h”

#include “stdlib.h”

#define LEN 10

/*環(huán)形隊列結(jié)構(gòu)體*/

typedef struct ring_buff{

int array[LEN];

int W;

int R;

}*ring;

/*環(huán)形隊列初始化*/

struct ring_buff * fifo_init(void)

{

struct ring_buff * p = NULL;

p = (struct ring_buff *)malloc(sizeof(struct ring_buff));

if(p == NULL)

{

printf(“fifo_init malloc error

”);

return NULL;

}

p-》W = 0;

p-》R = 0;

return p;

}

/*判斷環(huán)形隊列是否已經(jīng)滿了*/

int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)

{

/*如果寫位置減去讀位置等于隊列長度,就說明這個環(huán)形隊列已經(jīng)滿*/

if((p_ring_buff-》W - p_ring_buff-》R) == LEN)

{

return (1);

}

else

{

return (0);

}

}

/*判斷環(huán)形隊列為空*/

int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)

{

/*如果寫位置和讀的位置相等,就說明這個環(huán)形隊列為空*/

if(p_ring_buff-》W == p_ring_buff-》R)

{

return (1);

}

else

{

return (0);

}

}

/*插入數(shù)據(jù)*/

int ring_buff_insert(struct ring_buff * p_ring_buff,int data)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_fullstate(p_ring_buff) == 1)

{

printf(“buff is full

”);

return (-2);

}

p_ring_buff-》array[p_ring_buff-》W%LEN] = data;

p_ring_buff-》W ++;

//printf(“inset:%d %d

”,data,p_ring_buff-》W);

return (0);

}

/*讀取環(huán)形隊列數(shù)據(jù)*/

int ring_buff_get(struct ring_buff * p_ring_buff)

{

int data = 0;

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_emptystate(p_ring_buff) == 1)

{

printf(“buff is empty

”);

return (-2);

}

data = p_ring_buff-》array[p_ring_buff-》R%LEN];

p_ring_buff-》R++;

return data;

}

/*銷毀*/

int ring_buff_destory(struct ring_buff * p_ring_buff)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

free(p_ring_buff);

return (0);

}

int main()

{

int i = 0;

/*定義一個環(huán)形緩沖區(qū)*/

ring pt_ring_buff = fifo_init();

/*向環(huán)形緩沖區(qū)中寫入數(shù)據(jù)*/

for(i = 0;i《10;i++)

{

ring_buff_insert(pt_ring_buff,i);

}

/*從環(huán)形緩沖區(qū)中讀出數(shù)據(jù)*/

for(i = 0;i《10;i++)

{

printf(“%d ”,ring_buff_get(pt_ring_buff));

}

/*銷毀一個環(huán)形緩沖區(qū)*/

ring_buff_destory(pt_ring_buff);

return (1);

}

599cb322-b20d-11eb-bf61-12bb97331649.png

換一個寫法,這個寫法是各種大神級別的

/* 實現(xiàn)的最簡單的ringbuff 有更多提升空間,可以留言說明 */

#include “stdio.h”

#include “stdlib.h”

#define LEN 64

/*環(huán)形隊列結(jié)構(gòu)體*/

typedef struct ring_buff{

int array[LEN];

int W;

int R;

}*ring;

/*環(huán)形隊列初始化*/

struct ring_buff * fifo_init(void)

{

struct ring_buff * p = NULL;

p = (struct ring_buff *)malloc(sizeof(struct ring_buff));

if(p == NULL)

{

printf(“fifo_init malloc error

”);

return NULL;

}

p-》W = 0;

p-》R = 0;

return p;

}

/*判斷環(huán)形隊列是否已經(jīng)滿了*/

int get_ring_buff_fullstate(struct ring_buff * p_ring_buff)

{

/*如果寫位置減去讀位置等于隊列長度,就說明這個環(huán)形隊列已經(jīng)滿*/

if((p_ring_buff-》W - p_ring_buff-》R) == LEN)

{

return (1);

}

else

{

return (0);

}

}

/*判斷環(huán)形隊列為空*/

int get_ring_buff_emptystate(struct ring_buff * p_ring_buff)

{

/*如果寫位置和讀的位置相等,就說明這個環(huán)形隊列為空*/

if(p_ring_buff-》W == p_ring_buff-》R)

{

return (1);

}

else

{

return (0);

}

}

/*插入數(shù)據(jù)*/

int ring_buff_insert(struct ring_buff * p_ring_buff,int data)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_fullstate(p_ring_buff) == 1)

{

printf(“buff is full

”);

return (-2);

}

//p_ring_buff-》array[p_ring_buff-》W%LEN] = data;

p_ring_buff-》array[p_ring_buff-》W&(LEN -1)] = data;

p_ring_buff-》W ++;

//printf(“inset:%d %d

”,data,p_ring_buff-》W);

return (0);

}

/*讀取環(huán)形隊列數(shù)據(jù)*/

int ring_buff_get(struct ring_buff * p_ring_buff)

{

int data = 0;

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

if(get_ring_buff_emptystate(p_ring_buff) == 1)

{

printf(“buff is empty

”);

return (-2);

}

//data = p_ring_buff-》array[p_ring_buff-》R%LEN];

data = p_ring_buff-》array[p_ring_buff-》R&(LEN -1)];

p_ring_buff-》R++;

return data;

}

/*銷毀*/

int ring_buff_destory(struct ring_buff * p_ring_buff)

{

if(p_ring_buff == NULL)

{

printf(“p null

”);

return (-1);

}

free(p_ring_buff);

return (0);

}

int main()

{

int i = 0;

/*定義一個環(huán)形緩沖區(qū)*/

ring pt_ring_buff = fifo_init();

/*向環(huán)形緩沖區(qū)中寫入數(shù)據(jù)*/

for(i = 0;i《10;i++)

{

ring_buff_insert(pt_ring_buff,i);

}

/*從環(huán)形緩沖區(qū)中讀出數(shù)據(jù)*/

for(i = 0;i《10;i++)

{

printf(“%d ”,ring_buff_get(pt_ring_buff));

}

/*銷毀一個環(huán)形緩沖區(qū)*/

ring_buff_destory(pt_ring_buff);

return (1);

}

總結(jié)

環(huán)形隊列的使用場景非常多,安卓的音頻數(shù)據(jù)讀寫,很多都用到環(huán)形隊列,我們在開發(fā)過程中使用的環(huán)形隊列肯定比我上面的那個例子要復(fù)雜的多,我這里演示的是比較簡單的功能,但是麻雀雖小,五臟俱全,希望這個麻雀讓你們了解這個數(shù)據(jù)結(jié)構(gòu)。在實際項目中大展身手。

原文標題:C語言實現(xiàn)環(huán)形隊列的原理和方法

文章出處:【微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

責任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7256

    瀏覽量

    91821
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141643

原文標題:C語言實現(xiàn)環(huán)形隊列的原理和方法

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    RabbitMQ消息隊列解決方案

    在現(xiàn)代分布式系統(tǒng)架構(gòu)中,消息隊列作為核心組件,承擔著系統(tǒng)解耦、異步處理、流量削峰等重要職責。RabbitMQ作為一款成熟的消息隊列中間件,以其高可用性、高可靠性和豐富的特性,成為眾多企業(yè)的首選方案。本文將從運維工程師的角度,詳細闡述RabbitMQ從單機部署到集群搭建的完
    的頭像 發(fā)表于 07-08 15:55 ?175次閱讀

    NVME控制器之隊列管理模塊

    隊列管理模塊是整個NVMe Host控制器的核心模塊,該模塊實現(xiàn)了提交隊列與完成隊列的管理,多隊列請求的仲裁判決等功能。隊列管理模塊中含有數(shù)
    的頭像 發(fā)表于 05-03 15:32 ?186次閱讀
    NVME控制器之<b class='flag-5'>隊列</b>管理模塊

    深入理解C語言C語言循環(huán)控制

    C語言編程中,循環(huán)結(jié)構(gòu)是至關(guān)重要的,它可以讓程序重復(fù)執(zhí)行特定的代碼塊,從而提高編程效率。然而,為了避免程序進入無限循環(huán),C語言提供了多種循環(huán)控制語句,如break、continue和
    的頭像 發(fā)表于 04-29 18:49 ?1131次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>C</b><b class='flag-5'>語言</b>循環(huán)控制

    淺談環(huán)形鐵心兼談環(huán)形變壓器

    近年來,在電子市場上,環(huán)形變壓器已廣泛用于家庭影院和多種電子設(shè)備中,而繞制環(huán)形變壓器所用的鐵心即環(huán)形鐵心,可分A、B兩種系列,現(xiàn)介紹如下: 1. A系列環(huán)形鐵心 A系列
    發(fā)表于 04-16 15:04

    C語言的歷史及程序介紹

    電子發(fā)燒友網(wǎng)站提供《C語言的歷史及程序介紹.pdf》資料免費下載
    發(fā)表于 04-09 16:10 ?0次下載

    環(huán)形器的特點和應(yīng)用

    環(huán)形器是一個有單向傳輸特性的三端口器件,它表明器件從1到2,從2到3 和從3到1是導(dǎo)通的,反過來信號從2到1,從3到2和從1到3是隔離的。環(huán)形器是有數(shù)個端的非可逆器件。
    的頭像 發(fā)表于 11-29 16:49 ?2831次閱讀
    <b class='flag-5'>環(huán)形</b>器的<b class='flag-5'>特點</b>和應(yīng)用

    JavaWeb消息隊列使用指南

    在現(xiàn)代的JavaWeb應(yīng)用中,消息隊列(Message Queue)是一種常見的技術(shù),用于異步處理任務(wù)、解耦系統(tǒng)組件、提高系統(tǒng)性能和可靠性。 1. 消息隊列的基本概念 消息隊列是一種應(yīng)用程序?qū)?yīng)
    的頭像 發(fā)表于 11-25 09:27 ?517次閱讀

    C語言指針學(xué)習筆記

    本文從底層內(nèi)存分析,徹底讓讀者明白C語言指針的本質(zhì)。
    的頭像 發(fā)表于 11-05 17:40 ?639次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>指針學(xué)習筆記

    C語言C++中結(jié)構(gòu)體的區(qū)別

    同樣是結(jié)構(gòu)體,看看在C語言C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?766次閱讀

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領(lǐng)域中的重要成員,它們各自具有獨特的優(yōu)勢和特點,適用于不同的應(yīng)用場景。以下將從語法特性、內(nèi)存管理、跨平臺性、性能、應(yīng)用領(lǐng)域等多個方面對
    的頭像 發(fā)表于 10-29 17:31 ?1069次閱讀

    C語言與其他編程語言的比較

    C語言作為一種歷史悠久的編程語言,自其誕生以來,一直在軟件開發(fā)領(lǐng)域扮演著重要角色。它以其高效、靈活和可移植性強的特點,成為了系統(tǒng)級編程的首選語言
    的頭像 發(fā)表于 10-29 17:30 ?1075次閱讀

    嵌入式環(huán)形隊列與消息隊列的實現(xiàn)原理

    嵌入式環(huán)形隊列,也稱為環(huán)形緩沖區(qū)或循環(huán)隊列,是一種先進先出(FIFO)的數(shù)據(jù)結(jié)構(gòu),用于在固定大小的存儲區(qū)域中高效地存儲和訪問數(shù)據(jù)。其主要特點
    的頭像 發(fā)表于 09-02 15:29 ?1246次閱讀

    環(huán)形變壓器輸出是直流還是交流

    環(huán)形變壓器是一種特殊類型的變壓器,其主要特點是鐵芯的形狀為環(huán)形,這種設(shè)計可以減小變壓器的體積和重量,同時提高效率和降低噪音。環(huán)形變壓器廣泛應(yīng)用于各種電子設(shè)備中,如電源適配器、開關(guān)電源、
    的頭像 發(fā)表于 08-21 09:45 ?1697次閱讀

    玩轉(zhuǎn)RT-Thread之消息隊列的應(yīng)用

    不同來源的數(shù)據(jù),確保系統(tǒng)的穩(wěn)定性和響應(yīng)速度。一、設(shè)計消息結(jié)構(gòu)二、創(chuàng)建消息隊列在service.c文件中,我們需要創(chuàng)建一個消息隊列來存放這些消息,并在處理線程中接收和
    的頭像 發(fā)表于 07-23 08:11 ?910次閱讀
    玩轉(zhuǎn)RT-Thread之消息<b class='flag-5'>隊列</b>的應(yīng)用

    C++語言基礎(chǔ)知識

    電子發(fā)燒友網(wǎng)站提供《C++語言基礎(chǔ)知識.pdf》資料免費下載
    發(fā)表于 07-19 10:58 ?10次下載