c/c++ 多線程 等待一次性事件 packaged_task用法

来源:https://www.cnblogs.com/xiaoshiwang/archive/2018/11/24/10014219.html
-Advertisement-
Play Games

多線程 等待一次性事件 packaged_task用法 背景:不是很明白,不知道為瞭解決什麼業務場景,感覺std::asynck可以優雅的搞定一切,一次等待性事件,為什麼還有個packaged_task。 用法:和std::async一樣,也能夠返回std::future,通過調用get_futur ...


多線程 等待一次性事件 packaged_task用法

背景:不是很明白,不知道為瞭解決什麼業務場景,感覺std::asynck可以優雅的搞定一切,一次等待性事件,為什麼還有個packaged_task。

用法:和std::async一樣,也能夠返回std::future,通過調用get_future方法。也可以通過future得到線程的返回值。

特點:

1,是個模板類,模板類型是個方法類型,比如double(int),有一個參數,類型是int,返回值類型是double。

std::packaged_task<double(int)> task(func);//func是個方法,有一個參數,類型是int,返回值類型是double

2,直接執行std::packaged_task的對象task時,不是非同步執行,是在原來的線程上阻塞執行,也就是說,只有task執行結束後,後面的代碼才能被執行,也就是說不是多線程執行。

std::packaged_task<std::string(int)> task1(call_texi);
std::future<std::string> ft1 = task1.get_future();
task1(100);//task1執行完成後,才能執行下麵的列印輸出的代碼,不是在新的線程里執行task1(100)
std::cout << "111111111111111111111111111111" << std::endl;

3,作為線程的參數時,用std::ref。把task放線上程里後,就是非同步執行了。

std::packaged_task<std::string(int)> task1(call_texi);
std::future<std::string> ft1 = task1.get_future();
std::thread t1(std::ref(task1), 100);
t1.detach();//task1(100)是非同步執行,也就是在新的線程里執行。
std::cout << "111111111111111111111111111111" << std::endl;

代碼:

#include <deque>
#include <mutex>
#include <future>
#include <thread>
#include <iostream>
#include <unistd.h>
#include <string>
//#include <utility>

std::mutex mut;
std::deque<std::packaged_task<std::string(int)>> tasks;

void manage_tasks(){
  while(true){
    sleep(1);
    //std::cout << "please wait for a moument" << std::endl;
    std::packaged_task<std::string(int)> task;
    {
      std::lock_guard<std::mutex> lg(mut);
      if(tasks.empty()) continue;
      std::cout << "----------------------not empty---------------" << std::endl;
      task = std::move(tasks.front());
      tasks.pop_front();
    }
    task(1);
    //std::string s = task(10);
  }
}

template<typename Call>
std::future<std::string> add_task(Call ca){
  std::cout << "----------------------add_task---------------" << std::endl;  
  std::packaged_task<std::string(int)> task(ca);
  std::future<std::string> ret = task.get_future();
  std::lock_guard<std::mutex> lg(mut);
  tasks.push_back(std::move(task));
  return ret;
}

std::string call_texi(int i = 0){
  std::cout << "-------------jiaoche---------------" << std::endl;
  if(i == 1){
    return "aaa";
  }else{
    return "bbb";
  }
}

std::string call_zhuanche(int i){
  std::cout << "zhuanche:" << i << std::endl;
  return std::to_string(i);
}
int main(){
  
  std::thread background_thread(manage_tasks);
  background_thread.detach();

  std::future<std::string> fut1 = add_task(call_texi);
  std::cout << fut1.get() << std::endl;
  
  std::future<std::string> fut2 = add_task(call_zhuanche);
  std::cout << fut2.get() << std::endl;

  pthread_exit(NULL);

}

github源代碼

編譯方法:

g++ -g XXX.cpp -std=c++11 -pthread

運行結果:

----------------------add_task---------------
----------------------not empty---------------
-------------jiaoche---------------
aaa
----------------------add_task---------------
----------------------not empty---------------
zhuanche:1
1

代碼分析:在隊列里保存std::packaged_task,啟動一個後臺線程background_thread,上鎖,監視隊列里是否有了新的task,有了新的task,就取出來用右值賦值的方式,然後出隊這個task,解鎖。執行這個task。

迷惑點:

  • add_task的調用時點,是可以知道傳遞什麼參數的,但是調用add_task時,由於語法的限制不能夠把參數傳遞給call_zhuanche方法或者call_taxi方法,只有在manage_tasks方法里調用task方法時,才能夠傳遞參數,可是在這個時點,參數從哪裡來???求大神指點!!!

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • setInterval()和setTimeout()方法都是js原生的定時方法,當然它們兩個的作用也是不同的,並且最近在做上下滾動公告欄的時候,發現了setInterval()非常令人抓狂的問題,那就是用setInterval()做的定時滾動會隨著瀏覽器頁面切換變得無法控制!為什麼會說無法控制呢,因 ...
  • @[toc] 轉載請註明出處 初識jQuery 為什麼要使用jQuery? 1.什麼是jquery? jQuery是js的一個庫,簡化了js代碼的書寫(註:jQuery語句中用逗號分隔各個css,因為一條css對應一個對象屬性,對象屬性之間是用逗號分隔而非分號) 舉例: 例1:簡化了獲取元素的語句 ...
  • 本文針對react navigation^3.0.0版本,版本不對的話,請不要看本文,直接看官方英文文檔 ​ 最近一直在學習RN,沒找到什麼好的視頻,所以一直看文檔,一路上來雖然遇到一些亂七八糟的bug,但是能比較友好的解決掉 直到我使用 ,這個官方文檔上說 的導航組件,搞的我心態爆照,調試了一下午 ...
  • 微服務的目標是通過將應用程式分解為可以獨立部署的小型自治服務來提高應用程式版本的速度。微服務架構也帶來了一些挑戰,這些模式可以幫助緩解這些挑戰。設計模式(design pattern)是對軟體設計中普遍存在(反覆出現)的各種問題,所提出的解決方案。當然微服務中的雲設計模式也是對微服務中普遍存在的問題... ...
  • 一.在Servlet中,表單提交的非字元串類型需要手動轉換 1.在struts中,表單提供的常見數據類型struts框架自動轉換,無需手動轉換 2.在某些情況下,某些自定義類型struts不能完成自動轉換,需要進行手動轉換,如果需要轉換的類型轉換頻率較高時,手動轉換的代碼增多,這時可以使用strut ...
  • 撩課Java+系統架構 視頻 點擊開始學習 81.Servlet的會話機制? 82.Filter是什麼?有什麼作用? 83.Listener是什麼?有什麼作用? 84.你瞭解過Servlet3.0嗎? 85.JSP和Servlet有哪些相同點和不同點? ...
  • 2018-11-24 22:57:33 問題說明 最近看到Spring事務,在學習過程中遇到一個很苦惱問題 搭建好Spring的啟動環境後出現了一點小問題 在啟動時候卻出現[java.lang.NullPointerException] 不過因為當時一個小小的疏忽 很low的問題 請往下看 ... ...
  • 從高位開始逐位輸出一個整數的各位數字:輸入一個整數,從高位開始逐位分割並輸出它的各位數字。 include int main(void) { int i,j,m,n,s,k,a,b=0; scanf("%d",&m); k=m; do { m=m/10; b++; }while(m!=0); for ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...