最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++實現(xiàn)LinkBlockedQueue的問題

 更新時間:2020年10月26日 09:24:36   作者:封fenghl  
這篇文章主要介紹了c++實現(xiàn)LinkBlockedQueue的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

c++鏈表實現(xiàn)的阻塞隊列

最近從java源碼里發(fā)現(xiàn)了阻塞隊列的實現(xiàn),覺得非常有趣。

首先,介紹下什么是阻塞隊列。阻塞隊列代表著一個隊列可以線程安全的往該隊列中寫數(shù)據(jù)和從該隊列中讀數(shù)據(jù)。也就是說,我們可以在多個線程之間并發(fā)的進行寫數(shù)據(jù)和讀數(shù)據(jù),而不會引發(fā)任何并發(fā)問題。

下面我們就說說如何實現(xiàn)一個阻塞隊列。

而實現(xiàn)一個阻塞隊列的前提:

  1. 需要能夠使用鏈表實現(xiàn)一個隊列
  2. 能夠使用c++的鎖機制,去給隊列的寫和讀操作加鎖。

為了性能,這里的讀和寫的鎖不能是同一把鎖。而對于一個鏈表隊列來說,讀取操作肯定需要涉及頭指針,寫操作肯定涉及尾指針。既然要實現(xiàn)讀操作一把鎖和寫操作一把鎖。那么就要求讀操作只能更改頭指針而不能更改尾指針,寫操作只能更改尾指針而不能更改頭指針。不滿足這個要求,那么讀寫操作就不可能實現(xiàn)用兩把鎖分別對讀寫進行加鎖。

基本隊列的實現(xiàn)

現(xiàn)在我們先說說如何實現(xiàn)這個隊列。

要求:入隊操作(enqueue)只能操作尾指針(last), 出隊操作(dequeue)只能操作頭指針(head)。

對于隊列的初始化,這里不能單純的設置為空指針,需要將頭尾指針同一節(jié)點。

下面我們來看入隊操作如何實現(xiàn)

從這個入隊操作來看,該操作只更改了尾指針last, 而沒有更改頭指針head。

其代碼實現(xiàn)為:

 void enqueue(int item) {
    Node *node = new Node(item);
    last = last->next = node;
  }

接下來我們來看出隊操作如何實現(xiàn)

從出隊操作來看就有趣的多,它拋棄了head所指向的節(jié)點,而這個節(jié)點有可能是那些節(jié)點呢?

  • 初始化時所賦值的那個節(jié)點
  • 出隊后的節(jié)點

也就是說,head所指向的節(jié)點中的val值沒有任何實際含義。當需要出隊時,出隊head指向的下一個節(jié)點first中val的值,然后拋棄head本身指向的值,讓head指向head的下一個節(jié)點first,此時head原來所指向的節(jié)點將被刪除?,F(xiàn)在我們可以看出出隊操作也只改變了頭指針head的值。

其代碼實現(xiàn)為:

 int dequeue() {
    Node *h = head;
    Node *first = head->next;
    delete h;
    head = first;
    int x = first->item;
    return x;
  }

現(xiàn)在隊列已經(jīng)實現(xiàn),下面就看看阻塞隊列如何實現(xiàn)。

阻塞隊列的實現(xiàn)

既然是阻塞隊列,那就意味這加鎖和等待。那就需要對c++的一些鎖知識和條件變量有了解。

先來看看我們需要實現(xiàn)阻塞隊列的那些方法:

Special Value Blocks Times out
Insert offer(o) put(o) offer(o,timeout)
Remove poll() take() poll(timeout)

入隊

讓我們先來實現(xiàn)put這個方法。

先看其實現(xiàn)流程圖:

由于該隊列實現(xiàn)有最大值限制,故在插入數(shù)據(jù)之前需要先判斷該隊列是否已滿,已滿則需等待該隊列有可用空間。在該線程入隊操作完成后,可能有別的線程也在等待入隊,需要喚醒其他寫數(shù)據(jù)的線程,使其繼續(xù)執(zhí)行后續(xù)操作。如果入隊前隊列為空,可能有出隊操作正在阻塞等待讀數(shù),也需要去喚醒讀數(shù)據(jù)的線程。

在看代碼實現(xiàn)之前,我們需要定義一些變量用于代碼實現(xiàn)環(huán)節(jié):

 /* The capacity bound*/
  int64_t capacity;
  /*Current number of elements */
  std::atomic<int64_t> count;  
	/** Lock held by take, pool, etc */
  std::mutex takeLock;
  /** Wait queue for waiting takes */
  std::condition_variable notEmpty;
  /** Lock held by put, offer, etc */
  std::mutex putLock;
  /** Wait queue for waiting puts */
  std::condition_variable notFull;

put函數(shù)的代碼實現(xiàn):

void LinkedBlockingQueue::put(const int item){
  int c;
  {
    std::unique_lock<std::mutex> lck{putLock};
    if( count == capacity) {
      notFull.wait(lck, [this](){return count < capacity;}); //(1)
    }
    enqueue(item); //不應該把申請空間放在鎖里面,耗時有點大
    c = count.fetch_add(1);
  }
  if(c + 1 < capacity) {
    notFull.notify_one();
  }

  if(0 == c) {
    notEmpty.notify_one();
  }
}

對于offer(o)的實現(xiàn),主要更改是對上述代碼(1)中的等待改為直接返回false, 表示,當前沒有可用空間插入數(shù)據(jù)。正常插入就返回true.

對于offer(o,timeout)的實現(xiàn),就需要在上述代碼(1)中的wait函數(shù)添加上時間參數(shù),使其可以在timeout時間內(nèi)返回,如果是正常喚醒,正常入隊,則返回ture,否則返回false.

該更改為:

 if(!notFull.wait_for(lck, rel_time, [this](){return count < capacity;})){
        return false;
      }

出隊

對于出隊,其實現(xiàn)和入隊基本相同,基本上只需要更改其中的關鍵判斷和通知。

take函數(shù)的代碼實現(xiàn)為:

void LinkedBlockingQueue::take(int & returnVal) {
  int c;
  {
    std::unique_lock<std::mutex> lck{takeLock};
    if( 0 == count) {
      notEmpty.wait(lck, [this](){return count > 0 ;});
    }
    returnVal = dequeue();
    c = count.fetch_sub(1);
  }

  if( c > 1 ) {
    notEmpty.notify_one();
  }

  if(c == capacity) {
    notFull.notify_one();
  }
}

剩下的實現(xiàn)細節(jié)可以參考我的實現(xiàn)

到此這篇關于c++實現(xiàn)LinkBlockedQueue的問題的文章就介紹到這了,更多相關c++實現(xiàn)LinkBlockedQueue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • c++ 隨機數(shù)問題的相關研究

    c++ 隨機數(shù)問題的相關研究

    這篇文章主要介紹了c++ 隨機數(shù)問題的相關研究,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下
    2021-03-03
  • C語言版三子棋游戲實現(xiàn)代碼

    C語言版三子棋游戲實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了C語言版三子棋游戲的實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C語言深入探究冒泡排序與堆排序使用案例講解

    C語言深入探究冒泡排序與堆排序使用案例講解

    算法中排序是十分重要的,而每一個學習計算機的都會在初期的時候接觸到這種排序,下面這篇文章主要給大家介紹了關于c語言冒泡排序與堆排序使用的相關資料,需要的朋友可以參考下
    2022-05-05
  • C++ 中的 if-constexpr語法和作用

    C++ 中的 if-constexpr語法和作用

    ?if-constexpr語法是 C++ 17 引入的新語法特性,也被稱為常量 if 表達式或靜態(tài) if(static if),這篇文章主要介紹了C++ 中的 if-constexpr語法和作用,需要的朋友可以參考下
    2025-03-03
  • C++深入淺出講解希爾排序算法的實現(xiàn)

    C++深入淺出講解希爾排序算法的實現(xiàn)

    希爾排序是希爾(Donald Shell)于1959年提出的一種排序算法。希爾排序也是一種插入排序,它是簡單插入排序經(jīng)過改進之后的一個更高效的版本,也稱為縮小增量排序,同時該算法是沖破O(n2)的第一批算法之一。本文會以圖解的方式詳細介紹希爾排序的基本思想及其代碼實現(xiàn)
    2022-05-05
  • 實例講解C++ 命名空間

    實例講解C++ 命名空間

    這篇文章主要介紹了C++ 命名空間的的相關資料,文中示例代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解下
    2020-06-06
  • C++大整數(shù)加法解題思路及參考代碼

    C++大整數(shù)加法解題思路及參考代碼

    大整數(shù)加法的思路是用兩個數(shù)組儲存兩個整數(shù)的每一位然后分別相加,下面這篇文章主要給大家介紹了關于C++大整數(shù)加法解題思路及參考代碼的相關資料,需要的朋友可以參考下
    2024-03-03
  • C++開發(fā)protobuf動態(tài)解析工具

    C++開發(fā)protobuf動態(tài)解析工具

    這篇文章主要為大家介紹了C++開發(fā)protobuf動態(tài)解析工具實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • OpenCV實現(xiàn)圖像去噪算法的步驟詳解

    OpenCV實現(xiàn)圖像去噪算法的步驟詳解

    這篇文章主要為大家介紹了OpenCV中圖像去噪算法的原理,文中通過示例為大家詳細講解了圖像去噪算法的使用,感興趣的小伙伴可以了解一下
    2022-06-06
  • C++將CBitmap類中的圖像保存到文件的方法

    C++將CBitmap類中的圖像保存到文件的方法

    這篇文章主要介紹了C++將CBitmap類中的圖像保存到文件的方法,涉及C++導出資源文件的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07

最新評論

科尔| 繁昌县| 商丘市| 莱芜市| 浑源县| 巧家县| 卢湾区| 塔城市| 舟山市| 马关县| 婺源县| 广汉市| 全椒县| 绥宁县| 大荔县| 无极县| 平阴县| 汝城县| 牙克石市| 广水市| 辽中县| 洪江市| 马尔康县| 股票| 图们市| 金门县| 安溪县| 崇义县| 栖霞市| 桐乡市| 凉城县| 阳高县| 和政县| 垣曲县| 昌吉市| 井研县| 茶陵县| 云南省| 洛阳市| 海丰县| 宁武县|