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

[數(shù)據(jù)結(jié)構(gòu)-1]:環(huán)形buffer以及讀寫同步

這篇具有很好參考價值的文章主要介紹了[數(shù)據(jù)結(jié)構(gòu)-1]:環(huán)形buffer以及讀寫同步。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、什么是環(huán)形buffer

二、環(huán)形buffer的優(yōu)點與使用場合

三、環(huán)節(jié)buffer的讀寫同步

3.1 基本原理

3.2 代碼示例


一、什么是環(huán)形buffer

環(huán)形緩沖區(qū)(Circular Buffer)也被稱為環(huán)形隊列(Circular Queue)或循環(huán)緩沖區(qū),是一種數(shù)據(jù)結(jié)構(gòu),用于在固定大小的緩沖區(qū)中存儲和處理數(shù)據(jù)。

環(huán)形緩沖區(qū)的特點是首尾相連,即緩沖區(qū)的最后一個元素和第一個元素相鄰。當(dāng)緩沖區(qū)寫滿時,新數(shù)據(jù)可以覆蓋舊數(shù)據(jù),實現(xiàn)循環(huán)利用。

環(huán)形緩沖區(qū)常見的應(yīng)用場景是數(shù)據(jù)流處理,例如音頻、視頻、網(wǎng)絡(luò)通信等。它具有以下優(yōu)點:

  1. 內(nèi)存利用率高:由于循環(huán)利用,不會浪費(fèi)內(nèi)存空間。
  2. 讀寫效率高:讀寫指針移動固定步長,無需頻繁移動指針或進(jìn)行數(shù)據(jù)搬移操作。
  3. 簡單且高效:相比其他數(shù)據(jù)結(jié)構(gòu),環(huán)形緩沖區(qū)操作簡單,性能高。

環(huán)形緩沖區(qū)的實現(xiàn)通常需要兩個指針,表示讀和寫的位置。讀指針用于提取數(shù)據(jù),寫指針用于寫入數(shù)據(jù)。同時,還需要記錄緩沖區(qū)的大小和當(dāng)前數(shù)據(jù)元素的數(shù)量。

通過合理管理讀寫指針和計數(shù)信息,可以實現(xiàn)有效的數(shù)據(jù)讀寫和同步,避免數(shù)據(jù)溢出和讀寫沖突的問題。

二、環(huán)形buffer的優(yōu)點與使用場合

環(huán)形緩沖區(qū)(Circular Buffer)具有以下優(yōu)點和適用場合:

優(yōu)點:

  1. 內(nèi)存利用率高:環(huán)形緩沖區(qū)能夠循環(huán)利用緩沖區(qū)的空間,不會浪費(fèi)內(nèi)存。當(dāng)緩沖區(qū)寫滿時,新的數(shù)據(jù)可以覆蓋舊的數(shù)據(jù),避免了頻繁地分配和釋放內(nèi)存空間的開銷。
  2. 讀寫效率高:環(huán)形緩沖區(qū)的讀寫操作只涉及指針的移動,不需要進(jìn)行元素的搬移或內(nèi)存復(fù)制,因此讀寫效率較高。讀寫指針以固定步長移動,無需頻繁更新指針位置,特別適用于實時數(shù)據(jù)的處理。
  3. 簡單且高效:相比其他數(shù)據(jù)結(jié)構(gòu),環(huán)形緩沖區(qū)的實現(xiàn)較為簡單,并且具有較高的性能。它不需要復(fù)雜的內(nèi)存管理或鏈表操作,可以快速讀寫數(shù)據(jù)。

使用場合:

  1. 數(shù)據(jù)流處理:環(huán)形緩沖區(qū)常用于處理連續(xù)的數(shù)據(jù)流,例如音頻、視頻、傳感器數(shù)據(jù)等。通過循環(huán)利用緩沖區(qū)的空間,可實現(xiàn)高效的數(shù)據(jù)流存儲以及快速的讀取和處理。
  2. 緩沖數(shù)據(jù)傳輸:環(huán)形緩沖區(qū)可以用于緩沖數(shù)據(jù)的傳輸,特別是在生產(chǎn)者和消費(fèi)者之間的數(shù)據(jù)傳輸場景。通過緩沖區(qū),可以平衡生產(chǎn)者和消費(fèi)者的速度差異,避免數(shù)據(jù)丟失或阻塞。
  3. 數(shù)據(jù)采樣和循環(huán)記錄:環(huán)形緩沖區(qū)適用于需要采樣和記錄連續(xù)數(shù)據(jù)的應(yīng)用。例如嵌入式系統(tǒng)中的數(shù)據(jù)采集、實時監(jiān)控系統(tǒng)中的歷史數(shù)據(jù)記錄等。
  4. 實時任務(wù)調(diào)度:在實時任務(wù)調(diào)度中,環(huán)形緩沖區(qū)可用于存儲任務(wù)隊列。任務(wù)按照優(yōu)先級或時間順序排列,通過環(huán)形緩沖區(qū)的循環(huán)讀取,可以高效地完成實時任務(wù)的調(diào)度和執(zhí)行。

總之,環(huán)形緩沖區(qū)適用于需要循環(huán)讀寫、高效利用內(nèi)存和處理連續(xù)數(shù)據(jù)的場景,可以提高數(shù)據(jù)處理的效率和性能。

三、環(huán)節(jié)buffer的讀寫同步

3.1 基本原理

在環(huán)形buffer中,讀和寫的同步通??梢酝ㄟ^使用信號量來實現(xiàn)。環(huán)形buffer的同步通常需要維護(hù)兩個指針:read_indexwrite_index,分別表示當(dāng)前讀取到的位置和下一個寫入的位置。

讀取操作需要獲取已經(jīng)寫入的數(shù)據(jù),因此需要等待直到有數(shù)據(jù)可用。這可以通過一個信號量來實現(xiàn),信號量的值初始化為0,并在寫操作完成時加1。每次讀取操作首先嘗試獲取信號量,如果信號量的值<=0,則表示沒有數(shù)據(jù)可用,需要等待。當(dāng)信號量的值>0時,讀取操作將從環(huán)形buffer中讀取數(shù)據(jù),更新read_index指針,并將信號量的值減1。

寫入操作也需要同步,因為當(dāng)buffer寫滿后就不能再寫入新的數(shù)據(jù)了。寫入操作同樣需要使用一個信號量,該信號量的值初始化為buffer的大小,并在讀取操作完成時加1。每次寫入操作首先嘗試獲取信號量,如果信號量的值<=0,則表示buffer已經(jīng)寫滿,需要等待。當(dāng)信號量的值>0時,寫入操作將寫入數(shù)據(jù)到環(huán)形buffer中,更新write_index指針,并將信號量的值減1。

這樣,通過使用信號量,可以實現(xiàn)環(huán)形buffer的讀和寫的同步,避免了讀寫的沖突,以及buffer寫滿和讀取空buffer的情況。

3.2 代碼示例

以下是一個簡單的C++代碼示例,展示了如何在環(huán)形緩沖區(qū)中實現(xiàn)讀和寫的同步:

#include <iostream>
using namespace std;

const int BUFFER_SIZE = 10;

class CircularBuffer {
private:
  int buffer[BUFFER_SIZE];
  int readIndex;
  int writeIndex;
  int itemCount;

public:
  CircularBuffer() {
    readIndex = 0;
    writeIndex = 0;
    itemCount = 0;
  }

  bool isEmpty() {
    return (itemCount == 0);
  }

  bool isFull() {
    return (itemCount == BUFFER_SIZE);
  }

  void write(int data) {
    if (isFull()) {
      cout << "Buffer is full. Cannot write data." << endl;
      return;
    }

    buffer[writeIndex] = data;
    writeIndex = (writeIndex + 1) % BUFFER_SIZE;
    itemCount++;
    cout << "Data " << data << " has been written to buffer." << endl;
  }

  int read() {
    if (isEmpty()) {
      cout << "Buffer is empty. Cannot read data." << endl;
      return -1; // or any other suitable error value
    }

    int data = buffer[readIndex];
    readIndex = (readIndex + 1) % BUFFER_SIZE;
    itemCount--;
    cout << "Data " << data << " has been read from buffer." << endl;
    return data;
  }
};

int main() {
  CircularBuffer buffer;

  buffer.write(1);
  buffer.write(2);
  buffer.write(3);

  buffer.read();
  buffer.read();
  buffer.read();

  return 0;
}

在上面的示例中,CircularBuffer類表示環(huán)形緩沖區(qū),其構(gòu)造函數(shù)初始化了讀寫指針和計數(shù)項。isEmpty()和isFull()函數(shù)分別用于檢查緩沖區(qū)是否為空和是否已滿。

write(int data)函數(shù)用于將數(shù)據(jù)寫入緩沖區(qū),它先檢查緩沖區(qū)是否已滿,若已滿則輸出錯誤信息。若緩沖區(qū)未滿,則將數(shù)據(jù)寫入緩沖區(qū),同時更新寫指針和計數(shù)項。

read()函數(shù)用于從緩沖區(qū)讀取數(shù)據(jù),它先檢查緩沖區(qū)是否為空,若為空則輸出錯誤信息,并返回適當(dāng)?shù)腻e誤值。若緩沖區(qū)非空,則讀取數(shù)據(jù)到變量中,同時更新讀指針和計數(shù)項。

在主函數(shù)中創(chuàng)建了一個CircularBuffer對象,并進(jìn)行了幾次寫入和讀取操作,以展示緩沖區(qū)的同步行為。

請注意,該示例是一個簡要的示例,實際應(yīng)用中可能需要更多的同步保證和錯誤處理機(jī)制來處理并發(fā)訪問和異常情況。

3.3?環(huán)形buffer如何通過信號量實現(xiàn)讀和寫的同步, C++代碼示例

要實現(xiàn)環(huán)形緩沖區(qū)的讀和寫的同步,你可以使用兩個信號量來管理緩沖區(qū)的滿和空狀態(tài)。一個信號量用于表示緩沖區(qū)是否滿,另一個信號量用于表示緩沖區(qū)是否空。下面是使用信號量實現(xiàn)讀和寫同步的C++代碼示例:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;

const int BUFFER_SIZE = 10;

class CircularBuffer {
private:
  int buffer[BUFFER_SIZE];
  int readIndex;
  int writeIndex;
  int itemCount;
  
  mutex mtx;
  condition_variable bufferFull;
  condition_variable bufferEmpty;

public:
  CircularBuffer() {
    readIndex = 0;
    writeIndex = 0;
    itemCount = 0;
  }

  bool isEmpty() {
    return (itemCount == 0);
  }

  bool isFull() {
    return (itemCount == BUFFER_SIZE);
  }

  void write(int data) {
    unique_lock<mutex> lock(mtx);
    bufferFull.wait(lock, [this] { return !isFull(); });

    buffer[writeIndex] = data;
    writeIndex = (writeIndex + 1) % BUFFER_SIZE;
    itemCount++;
    cout << "Data " << data << " has been written to buffer." << endl;

    lock.unlock();
    bufferEmpty.notify_one();
  }

  int read() {
    unique_lock<mutex> lock(mtx);
    bufferEmpty.wait(lock, [this] { return !isEmpty(); });

    int data = buffer[readIndex];
    readIndex = (readIndex + 1) % BUFFER_SIZE;
    itemCount--;
    cout << "Data " << data << " has been read from buffer." << endl;

    lock.unlock();
    bufferFull.notify_one();

    return data;
  }
};

int main() {
  CircularBuffer buffer;

  thread writer([&buffer]() {
    for (int i = 1; i <= 5; i++) {
      buffer.write(i);
      this_thread::sleep_for(chrono::milliseconds(500));
    }
  });

  thread reader([&buffer]() {
    for (int i = 1; i <= 5; i++) {
      buffer.read();
      this_thread::sleep_for(chrono::seconds(1));
    }
  });

  writer.join();
  reader.join();

  return 0;
}

在上述代碼中,CircularBuffer類與之前的示例代碼類似。在類中添加了互斥鎖(mutex)mtx和條件變量(condition variable)bufferFull、bufferEmpty。mtx用于保護(hù)共享資源的互斥訪問,bufferFullbufferEmpty用于在讀寫操作中進(jìn)行等待和喚醒的同步。

write(int data)read()函數(shù)中,使用unique_lock來管理互斥鎖。在寫入操作中,調(diào)用bufferFull.wait()來等待緩沖區(qū)非滿的條件滿足,然后執(zhí)行寫入操作。在讀取操作中,調(diào)用bufferEmpty.wait()來等待緩沖區(qū)非空的條件滿足,然后執(zhí)行讀取操作。

當(dāng)寫入或讀取操作完成后,通過調(diào)用bufferEmpty.notify_one()bufferFull.notify_one()來喚醒等待的線程。

在主函數(shù)中創(chuàng)建了一個writer線程和一個reader線程,并分別模擬了寫入和讀取操作。使用chrono庫來控制線程的睡眠時間,以展示讀寫操作的同步行為。

需要注意的是,上述代碼僅提供了一個簡單的示例,實際應(yīng)用中可能需要更多的同步保證和錯誤處理機(jī)制,以及對信號量的正確使用和釋放。文章來源地址http://www.zghlxwxcb.cn/news/detail-838431.html

到了這里,關(guān)于[數(shù)據(jù)結(jié)構(gòu)-1]:環(huán)形buffer以及讀寫同步的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)OJ題】環(huán)形鏈表

    【數(shù)據(jù)結(jié)構(gòu)OJ題】環(huán)形鏈表

    原題鏈接:https://leetcode.cn/problems/linked-list-cycle/description/ 目錄 1. 題目描述 2. 思路分析 3. 代碼實現(xiàn) 整體思路: 定義 快慢指針fast,slow ,如果 鏈表確實有環(huán) , fast指針一定會在環(huán)內(nèi)追上slow指針。 即慢指針一次走一步,快指針一次走兩步,兩個指針從鏈表起始位置開始運(yùn)行,

    2024年02月12日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)OJ題】環(huán)形鏈表II

    【數(shù)據(jù)結(jié)構(gòu)OJ題】環(huán)形鏈表II

    原題鏈接:https://leetcode.cn/problems/linked-list-cycle-ii/description/ 如果有小伙伴不了解環(huán)形鏈表,可以先看看這篇文章: https://blog.csdn.net/m0_62531913/article/details/132352203?spm=1001.2014.3001.5502 我們來看下圖: ?我們根據(jù)這個結(jié)論就可以做出這道題目了!

    2024年02月12日
    瀏覽(19)
  • C語言每日一題:13《數(shù)據(jù)結(jié)構(gòu)》環(huán)形鏈表。

    C語言每日一題:13《數(shù)據(jù)結(jié)構(gòu)》環(huán)形鏈表。

    題目鏈接: 使用快慢指針利用相對移動的思想: 1,令快指針(fast)速度為2. 2.慢指針(slow)速度為1. 3.以慢指針進(jìn)入環(huán)中開始。 4。假設(shè)slow剛剛進(jìn)入環(huán)中fast與它相距N。 如圖所示: 1,令快指針(fast)速度為3.M 2.慢指針(slow)速度為1. 3.以慢指針進(jìn)入環(huán)中開始。 4。假設(shè)slow剛

    2024年02月14日
    瀏覽(24)
  • 從零開始學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)—【鏈表】—【探索環(huán)形鏈的設(shè)計之美】

    從零開始學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)—【鏈表】—【探索環(huán)形鏈的設(shè)計之美】

    雙向環(huán)形鏈表帶哨兵,這個時候的 哨兵 , 可以當(dāng)頭,也可做尾 帶哨兵雙向循環(huán)鏈表:結(jié)構(gòu)稍微復(fù)雜,實現(xiàn)簡單。一般用來單獨(dú)存儲數(shù)據(jù),實際中使用的鏈表數(shù)據(jù)結(jié)構(gòu)都是帶頭雙向鏈表。另外,這個結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜,但是使用代碼實現(xiàn)后會發(fā)現(xiàn)結(jié)構(gòu)會帶來很多優(yōu)勢。 雙向

    2024年02月22日
    瀏覽(32)
  • 【STM32 CubeMX】學(xué)STM必會的數(shù)據(jù)結(jié)構(gòu)——環(huán)形緩沖區(qū)

    【STM32 CubeMX】學(xué)STM必會的數(shù)據(jù)結(jié)構(gòu)——環(huán)形緩沖區(qū)

    在嵌入式系統(tǒng)開發(fā)中,經(jīng)常需要處理數(shù)據(jù)的緩存和傳輸,而環(huán)形緩沖區(qū)是一種常見且有效的數(shù)據(jù)結(jié)構(gòu),特別適用于處理實時數(shù)據(jù)流或者在有限的內(nèi)存資源下高效地管理數(shù)據(jù)。在STM32微控制器的開發(fā)中,使用CubeMX工具可以方便地配置和生成環(huán)形緩沖區(qū)的代碼,從而加速開發(fā)過程

    2024年04月12日
    瀏覽(42)
  • 【數(shù)據(jù)結(jié)構(gòu)】LeetCode升級版的環(huán)形鏈表,復(fù)制帶隨機(jī)指針的鏈表

    【數(shù)據(jù)結(jié)構(gòu)】LeetCode升級版的環(huán)形鏈表,復(fù)制帶隨機(jī)指針的鏈表

    ? ? ? ? ? 1、題目說明 ? ? ? ? ? 2、題目解析 ? ? ? ? ??1、題目說明 ? ? ? ? ? 2、題目解析 ? ? ?1、題目說明 題目鏈接: 升級版的環(huán)形鏈表? 給定一個鏈表的頭節(jié)點 head ,返回鏈表開始入環(huán)的第一個節(jié)點。? 如果鏈表無環(huán),則返回NULL。 如果鏈表中有某個節(jié)點,可以通

    2024年01月16日
    瀏覽(102)
  • 數(shù)據(jù)結(jié)構(gòu):帶環(huán)單鏈表基礎(chǔ)OJ練習(xí)筆記(leetcode142. 環(huán)形鏈表 II)(leetcode三題大串燒)

    數(shù)據(jù)結(jié)構(gòu):帶環(huán)單鏈表基礎(chǔ)OJ練習(xí)筆記(leetcode142. 環(huán)形鏈表 II)(leetcode三題大串燒)

    目錄 一.前言? 二.leetcode160.?相交鏈表? 1.問題描述 2.問題分析與求解 三.leetcode141.?環(huán)形鏈表 1.問題描述 2.代碼思路? 3.證明分析? 下一題會用到的重要小結(jié)論: 四.leetcode142.?環(huán)形鏈表 II 1.問題描述 2.問題分析與求解 Judgecycle接口: 方法一: 方法二:? 單鏈表和帶環(huán)單鏈表

    2023年04月08日
    瀏覽(20)
  • 【大數(shù)據(jù)】LSM樹,專為海量數(shù)據(jù)讀寫而生的數(shù)據(jù)結(jié)構(gòu)

    【大數(shù)據(jù)】LSM樹,專為海量數(shù)據(jù)讀寫而生的數(shù)據(jù)結(jié)構(gòu)

    目錄 1.什么是LSM樹? 2.LSM樹的落地實現(xiàn) LSM樹(Log-Structured Merge Tree)是一種專門針對大量寫操作做了優(yōu)化的數(shù)據(jù)存儲結(jié)構(gòu),尤其適用于現(xiàn)代大規(guī)模數(shù)據(jù)處理系統(tǒng),如NoSQL數(shù)據(jù)庫(如Cassandra、HBase、RocksDB等)和鍵值存儲。盡管其名稱中包含“樹”,但它并不直接對應(yīng)于傳統(tǒng)的樹狀

    2024年04月25日
    瀏覽(21)
  • Redis緩存讀寫策略(三種)數(shù)據(jù)結(jié)構(gòu)(5+3)

    Redis緩存讀寫策略(三種)數(shù)據(jù)結(jié)構(gòu)(5+3)

    Cache Aside Pattern 是我們平時使用比較多的一個緩存讀寫模式,比較適合讀請求比較多的場景。 寫 : 先更新 db 然后直接刪除 cache 。 讀 ?: 從 cache 中讀取數(shù)據(jù),讀取到就直接返回 cache 中讀取不到的話,就從 db 中讀取數(shù)據(jù)返回 再把數(shù)據(jù)放到 cache 中。 在寫數(shù)據(jù)的過程中,可以先

    2024年02月12日
    瀏覽(23)
  • MySQL一主一從、配置一主多從結(jié)構(gòu)、數(shù)據(jù)讀寫分離

    部署mysql主從同步 配置mysql主從 分為主數(shù)據(jù)庫角色(master)、從數(shù)據(jù)庫服務(wù)器角色(slave) 網(wǎng)站服務(wù)器連接后存儲數(shù)據(jù)的服務(wù)器作為主服務(wù)器 自動同步主服務(wù)器上的數(shù)據(jù) 192.168.88.53 做master 啟用binlog日志文件?指定server_id 重啟服務(wù) 用戶授權(quán) 查看正在使用的binlog日志文件 192.

    2024年01月19日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包