欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++11 多線程編程——如何實(shí)現(xiàn)線程安全隊(duì)列

 更新時(shí)間:2020年11月05日 09:58:14   作者:半杯茶的小酒杯  
這篇文章主要介紹了c++ 如何實(shí)現(xiàn)線程安全隊(duì)列,幫助大家更好的理解和學(xué)習(xí)c++的相關(guān)知識(shí),感興趣的朋友可以了解下

線程安全隊(duì)列的接口文件如下:

#include <memory> 
template<typename T>
class threadsafe_queue {
 public:
  threadsafe_queue();
  threadsafe_queue(const threadsafe_queue&);
  threadsafe_queue& operator=(const threadsafe_queue&) = delete;

  void push(T new_value);

  bool try_pop(T& value);
  std::shared_ptr<T> try_pop();

  void wait_and_pop(T& value);
  std::shared_ptr<T> wait_and_pop();

  bool empty() const;
};

push函數(shù)

push()函數(shù)實(shí)現(xiàn)向隊(duì)列添加數(shù)據(jù)的功能。添加數(shù)據(jù)后,使用std::condition_variable的notify_one通知取數(shù)據(jù)時(shí)被阻塞的線程。

void push(T tValue) {
  std::shared_ptr<T> data(std::make_shared<T>(std::move(tValue)));
  std::lock_guard<std::mutex> lk(mut);
  data_queue.push(data);
  data_con.notify_one();
}

wait_and_pop函數(shù)

wait_and_pop()函數(shù)實(shí)現(xiàn)從隊(duì)列取數(shù)據(jù)的功能,當(dāng)隊(duì)列為空時(shí),線程被掛起,等待有數(shù)據(jù)時(shí)被喚醒。

注意,這兩個(gè)函數(shù)中沒(méi)有使用std::lock_guard,而是使用std::unique_lock,這是為什么呢?

這是因?yàn)閟td::condition_variable的wait函數(shù)會(huì)首先檢測(cè)條件data_queue.empty()是否滿足,如果隊(duì)列為空,wait函數(shù)會(huì)釋放mutex,并被掛起;當(dāng)有新的數(shù)據(jù)進(jìn)入隊(duì)列,std::condition_variable的wait函數(shù)會(huì)被喚醒,重新嘗試獲取mutex,然后檢測(cè)隊(duì)列是否為空,如果隊(duì)列非空,則繼續(xù)向下執(zhí)行。由于函數(shù)的執(zhí)行過(guò)程存在鎖的釋放和重新獲取,所以沒(méi)有使用std::lock_guard,而是選擇了std::unique_lock。

void wait_and_pop(T& value) {
  std::unique_lock<std::mutex> lk(mut);
  data_cond.wait(lk,[this]{return !data_queue.empty();});
  value=data_queue.front();
  data_queue.pop();
}

std::shared_ptr<T> wait_and_pop() {
  std::unique_lock<std::mutex> lk(mut);
  data_cond.wait(lk,[this]{return !data_queue.empty();});
  std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
  data_queue.pop();
  return res;
}

try_pop函數(shù)

try_pop函數(shù)提供非阻塞調(diào)用下的彈出隊(duì)列(queue)的功能。彈出成功返回true或者非空shared_ptr,失敗則返回false或者nullptr。

bool try_pop(T& value) {
  std::lock_guard<std::mutex> lk(mut);
  if(data_queue.empty()) {
    return false;
  } 
  value = data_queue.front();
  data_queue.pop();
  
  return true;
}

std::shared_ptr<T> try_pop() {
  std::lock_guard<std::mutex> lk(mut);
  if(data_queue.empty()) {
    return std::shared_ptr<T>();
  }
  std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
  data_queue.pop();
  return res;
}

empty函數(shù)

bool empty() const {
  std::lock_guard<std::mutex> lk(mut);
  return data_queue.empty();
}

這里注意,empty()是const類(lèi)型的成員函數(shù),表明它聲明自己并不改變?nèi)魏纬蓡T變量,但是mutex lock是一個(gè)mutating opertation,所以必須要將mut聲明為mutable類(lèi)型(mutable std::mutex mut)。

完整代碼如下:

#include <queue>
#include <memory>
#include <mutex>
#include <condition_variable>

template<typename T>
class threadsafe_queue {
 private:
   mutable std::mutex mut; 
   std::queue<T> data_queue;
   std::condition_variable data_cond;
 public:
   threadsafe_queue(){}
   threadsafe_queue(threadsafe_queue const& other) {
     std::lock_guard<std::mutex> lk(other.mut);
     data_queue=other.data_queue;
   }

   void push(T new_value) {
     std::lock_guard<std::mutex> lk(mut);
     data_queue.push(new_value);
     data_cond.notify_one();
   }

   void wait_and_pop(T& value) {
     std::unique_lock<std::mutex> lk(mut);
     data_cond.wait(lk,[this]{return !data_queue.empty();});
     value=data_queue.front();
     data_queue.pop();
   }

   std::shared_ptr<T> wait_and_pop() {
     std::unique_lock<std::mutex> lk(mut);
     data_cond.wait(lk,[this]{return !data_queue.empty();});
     std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
     data_queue.pop();
     return res;
   }

   bool try_pop(T& value) {
     std::lock_guard<std::mutex> lk(mut);
     if(data_queue.empty())
       return false;
     value=data_queue.front();
     data_queue.pop();
     return true;
   }

   std::shared_ptr<T> try_pop() {
     std::lock_guard<std::mutex> lk(mut);
     if(data_queue.empty())
       return std::shared_ptr<T>();
     std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
     data_queue.pop();
     return res;
   }

   bool empty() const {
     std::lock_guard<std::mutex> lk(mut);
     return data_queue.empty();
   }
};

以上就是c++ 如何實(shí)現(xiàn)線程安全隊(duì)列的詳細(xì)內(nèi)容,更多關(guān)于c++ 線程安全隊(duì)列的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)一個(gè)閃爍的圣誕樹(shù)

    C語(yǔ)言實(shí)現(xiàn)一個(gè)閃爍的圣誕樹(shù)

    本文詳細(xì)講解了C語(yǔ)言實(shí)現(xiàn)一個(gè)閃爍的圣誕樹(shù),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • C語(yǔ)言中如何實(shí)現(xiàn)桶排序

    C語(yǔ)言中如何實(shí)現(xiàn)桶排序

    這篇文章主要介紹了C語(yǔ)言中如何實(shí)現(xiàn)桶排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 基于C語(yǔ)言實(shí)現(xiàn)2048游戲

    基于C語(yǔ)言實(shí)現(xiàn)2048游戲

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)2048游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C語(yǔ)言中的指針新手初階指南

    C語(yǔ)言中的指針新手初階指南

    指針是C語(yǔ)言的靈魂,精華之所在,指針強(qiáng)大而危險(xiǎn),用得好是一大利器,用得不好是一大潛在危害,下面這篇文章主要給大家介紹了C語(yǔ)言中指針的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • VC實(shí)現(xiàn)Windows多顯示器編程的方法

    VC實(shí)現(xiàn)Windows多顯示器編程的方法

    這篇文章主要介紹了VC實(shí)現(xiàn)Windows多顯示器編程的方法,涉及VC獲取屏幕分辨率及顯示參數(shù)等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • C++鏈接器工作原理詳解

    C++鏈接器工作原理詳解

    當(dāng)文件見(jiàn)過(guò)編譯后就需要進(jìn)行一個(gè)鏈接的操作接下來(lái)我們就說(shuō)說(shuō)什么是鏈接,本文給大家介紹了C++鏈接器是如何工作的,文章通過(guò)代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • 深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊

    深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊

    要求數(shù)據(jù)內(nèi)存的起始地址的值是某個(gè)數(shù)k的倍數(shù),這就是所謂的內(nèi)存對(duì)齊,本文就來(lái)深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊,需要的朋友可以參考下
    2016-05-05
  • 基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    這篇文章主要介紹了基于C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲,對(duì)于學(xué)習(xí)游戲開(kāi)發(fā)的朋友相信有一定的借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C++模擬Linux Shell編寫(xiě)一個(gè)自定義命令

    C++模擬Linux Shell編寫(xiě)一個(gè)自定義命令

    這篇文章主要介紹了C++如何模擬Linux Shell實(shí)現(xiàn)編寫(xiě)一個(gè)自定義命令,本文通過(guò)實(shí)例代碼進(jìn)行命令行解析,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • C/C++動(dòng)態(tài)分配與釋放內(nèi)存的區(qū)別詳細(xì)解析

    C/C++動(dòng)態(tài)分配與釋放內(nèi)存的區(qū)別詳細(xì)解析

    以下是對(duì)C與C++中動(dòng)態(tài)分配與釋放內(nèi)存的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09

最新評(píng)論