亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++11中多線程編程-std::async的深入講解

 更新時(shí)間:2020年11月02日 11:00:27   作者:MSBETA  
這篇文章主要給大家介紹了關(guān)于C++11中多線程編程-std::async的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

C++11中提供了異步線程接口std::async,std::async是異步編程的高級(jí)封裝,相對(duì)于直接使用std::thread,std::async的優(yōu)勢(shì)在于:

1、std::async會(huì)自動(dòng)創(chuàng)建線程去調(diào)用線程函數(shù),相對(duì)于低層次的std::thread,使用起來(lái)非常方便;

2、std::async返回std::future對(duì)象,通過(guò)返回的std::future對(duì)象我們可以非常方便的獲取到線程函數(shù)的返回結(jié)果;

3、std::async提供了線程的創(chuàng)建策略,可以指定同步或者異步的方式去創(chuàng)建線程;

1、函數(shù)原型

C++ 11中提供如下函數(shù)原型:

template< class Function, class... Args>
std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>>
 async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>>
 async( std::launch policy, Function&& f, Args&&... args );

其中,參數(shù)f接收一個(gè)可調(diào)用對(duì)象(仿函數(shù)、lambda表達(dá)式、類成員函數(shù)、普通函數(shù)……),用于異步或是同步執(zhí)行。

參數(shù)policy用于指定同步執(zhí)行或者異步執(zhí)行可調(diào)用對(duì)象,它的可選值有三種:

1)std::launch::async:異步執(zhí)行可調(diào)用對(duì)象;

2)std::launch::deferred:同步執(zhí)行可調(diào)用對(duì)象;

3)std::launch::async | std::launch::deferred 可以異步或是同步,取決于具體實(shí)現(xiàn)。

函數(shù)返回值:

函數(shù)返回值是std::future對(duì)象,我們可以執(zhí)行g(shù)et、wait、wait_for、wait_until函數(shù)獲取或者等待執(zhí)行結(jié)果。

調(diào)用std::future對(duì)象的get函數(shù)時(shí),如果執(zhí)行的是異步執(zhí)行策略,如果異步執(zhí)行沒(méi)有結(jié)束,get函數(shù)調(diào)用會(huì)阻塞當(dāng)前當(dāng)前調(diào)用線程;如果執(zhí)行的是同步執(zhí)行策略,只有當(dāng)調(diào)用get函數(shù)時(shí)才真正執(zhí)行。

調(diào)用std::future對(duì)象的wait*函數(shù)時(shí),可能返回三種狀態(tài):

1)std::future_status::deferred:可調(diào)用對(duì)象尚未開(kāi)始執(zhí)行;

2)std::future_status::ready:可調(diào)用對(duì)象執(zhí)行完畢;

3)std::future_status::timeout:可調(diào)用對(duì)象執(zhí)行超時(shí);

2、頭文件

#include <future>

3、同步或異步讀取文件內(nèi)容

我們模擬異步從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)和同步方式從文件中讀取數(shù)據(jù),從其中可以看到std::async的使用方法。

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
 
using namespace std::chrono;
 
std::string fetchDataFromDB(std::string recvData) {
 std::cout << "fetchDataFromDB start" << std::this_thread::get_id() << std::endl;
 std::this_thread::sleep_for(seconds(5));
 return "DB_" + recvData;
}
 
std::string fetchDataFromFile(std::string recvData) {
 std::cout << "fetchDataFromFile start" << std::this_thread::get_id() << std::endl;
 std::this_thread::sleep_for(seconds(3));
 return "File_" + recvData;
}
 
int main() {
 std::cout << "main start" << std::this_thread::get_id() << std::endl;
 
 //獲取開(kāi)始時(shí)間
 system_clock::time_point start = system_clock::now();
 
 std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
 
 //從文件獲取數(shù)據(jù)
 std::future<std::string> fileData = std::async(std::launch::deferred, fetchDataFromFile, "Data");
 
 //調(diào)用get函數(shù)fetchDataFromFile才開(kāi)始執(zhí)行
 std::string FileData = fileData.get();
 //如果fetchDataFromDB執(zhí)行沒(méi)有完成,get會(huì)一直阻塞當(dāng)前線程
 std::string dbData = resultFromDB.get();
 
 //獲取結(jié)束時(shí)間
 auto end = system_clock::now();
 
 auto diff = duration_cast<std::chrono::seconds>(end - start).count();
 std::cout << "Total Time taken= " << diff << "Seconds" << std::endl;
 
 //組裝數(shù)據(jù)
 std::string data = dbData + " :: " + FileData;
 
 //輸出組裝的數(shù)據(jù)
 std::cout << "Data = " << data << std::endl;
 
 return 0;
}

代碼輸出:

main start140677737994048
fetchDataFromFile start140677737994048
fetchDataFromDB start140677720131328
Total Time taken= 5Seconds
Data = DB_Data :: File_Data

4、設(shè)置異步數(shù)據(jù)讀取超時(shí)機(jī)制

有時(shí)我們不能無(wú)限制的等待異步任務(wù)執(zhí)行,可以設(shè)置超時(shí)等待時(shí)間(timeout),當(dāng)超時(shí)時(shí)間到達(dá)時(shí),可以選擇放棄等待異步任務(wù)。

如果代碼中,我們?cè)O(shè)置了1s的超時(shí)設(shè)置,用于檢查異步線程是否執(zhí)行完畢。

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
 
using namespace std::chrono;
 
std::string fetchDataFromDB(std::string recvData) {
 
 std::cout << "fetchDataFromDB start" << std::this_thread::get_id() << std::endl;
 std::this_thread::sleep_for(seconds(5));
 return "DB_" + recvData;
}
 
 
int main() {
 
 std::cout << "main start" << std::this_thread::get_id() << std::endl;
 
 //獲取開(kāi)始時(shí)間
 system_clock::time_point start = system_clock::now();
 
 std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
 
 std::future_status status;
 std::string dbData;
 do
 {
  status = resultFromDB.wait_for(std::chrono::seconds(1));
 
  switch (status)
  {
  case std::future_status::ready:
   std::cout << "Ready..." << std::endl;
   //獲取結(jié)果
   dbData = resultFromDB.get();
   std::cout << dbData << std::endl;
   break;
  case std::future_status::timeout:
   std::cout << "timeout..." << std::endl;
   break;
  case std::future_status::deferred:
   std::cout << "deferred..." << std::endl;
   break;
  default:
   break;
  }
 
 } while (status != std::future_status::ready);
 
 
 //獲取結(jié)束時(shí)間
 auto end = system_clock::now();
 
 auto diff = duration_cast<std::chrono::seconds>(end - start).count();
 std::cout << "Total Time taken= " << diff << "Seconds" << std::endl;
 
 return 0;
}

程序輸出:

main start140406593357632
fetchDataFromDB start140406575482624
timeout...
timeout...
timeout...
timeout...
Ready...
DB_Data
Total Time taken= 5Seconds

5、使用std::async實(shí)現(xiàn)多線程并發(fā)

既然std::async可以實(shí)現(xiàn)異步調(diào)用,我們很容易就可以借用它實(shí)現(xiàn)多線程并發(fā)。

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
#include <string>
#include <mutex>
#include <thread>
 
template <typename RandomIt>
int parallel_sum(RandomIt beg, RandomIt end)
{
 std::cout << "thread id:" << std::this_thread::get_id() << std::endl;
 
 auto len = end - beg;
 if (len < 1000)
  return std::accumulate(beg, end, 0);
 
 RandomIt mid = beg + len/2;
 auto handle_me = std::async(std::launch::async,
        parallel_sum<RandomIt>, mid, end);
 auto handle_bm = std::async(std::launch::async,
        parallel_sum<RandomIt>, beg, mid);
 // int sum = parallel_sum(beg, mid);
 return handle_bm.get() + handle_me.get();
}
 
int main()
{
 std::vector<int> v(10000, 1);
 std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << std::endl;
}

程序輸出如下:

The sum is thread id:140594794530624
thread id:140594776655616
thread id:140594768262912
thread id:140594759870208
thread id:140594672297728
thread id:140594680690432
thread id:140594663905024
thread id:140594655512320
thread id:140594647119616
thread id:140594638726912
thread id:140594269644544
thread id:140594630334208
thread id:140594278037248
thread id:140594252859136
thread id:140594261251840
thread id:140594252859136
thread id:140594236073728
thread id:140594252859136
thread id:140594261251840
thread id:140594630334208
thread id:140594244466432
thread id:140594252859136
thread id:140594227681024
thread id:140594261251840
thread id:140593875384064
thread id:140593850205952
thread id:140593858598656
thread id:140593866991360
thread id:140594647119616
thread id:140594269644544
thread id:140594672297728
10000

6、其它注意事項(xiàng)

在使用時(shí)需要注意,std::future對(duì)象的析構(gòu)需要等待std::async執(zhí)行完畢,也就是說(shuō),如下面的代碼并不能實(shí)現(xiàn)并發(fā)。原因在于std::async的返回的std::future對(duì)象無(wú)人接收,是個(gè)臨時(shí)變量,臨時(shí)變量的析構(gòu)會(huì)阻塞,直至std::async異步任務(wù)執(zhí)行完成。

std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
std::async(std::launch::async, []{ g(); }); // does not start until f() completes

參考材料

https://en.cppreference.com/w/cpp/thread/async

chabaoo.cn/article/198761.htm

總結(jié)

到此這篇關(guān)于C++11中多線程編程-std::async深入講解的文章就介紹到這了,更多相關(guān)C++11多線程編程-std::async內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++小知識(shí):用++i替代i++

    C++小知識(shí):用++i替代i++

    今天小編就為大家分享一篇關(guān)于C++小知識(shí):用++i替代i++,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • C語(yǔ)言實(shí)現(xiàn)乒乓球比賽

    C語(yǔ)言實(shí)現(xiàn)乒乓球比賽

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)乒乓球比賽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C/C++從零開(kāi)始的cmake教程

    C/C++從零開(kāi)始的cmake教程

    今天小編就為大家分享一篇關(guān)于C/C++從零開(kāi)始的cmake教程,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • 淺談C++繼承中的名字查找

    淺談C++繼承中的名字查找

    下面小編就為大家?guī)?lái)一篇淺談C++繼承中的名字查找。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • C語(yǔ)言詳解實(shí)現(xiàn)字符菱形的方法

    C語(yǔ)言詳解實(shí)現(xiàn)字符菱形的方法

    字符菱形是指給定一個(gè)字符,用它構(gòu)造一個(gè)對(duì)角線長(zhǎng)5個(gè)字符,傾斜放置的菱形。輸入輸入只有一行, 包含一個(gè)字符。輸出該字符構(gòu)成的菱形
    2022-04-04
  • C語(yǔ)言實(shí)現(xiàn)一個(gè)通訊錄

    C語(yǔ)言實(shí)現(xiàn)一個(gè)通訊錄

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)一個(gè)通訊錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++中的函數(shù)修飾符深入講解

    C++中的函數(shù)修飾符深入講解

    這篇文章主要給大家介紹了關(guān)于C++中函數(shù)修飾符的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • C++ Boost PropertyTree解析INI文件詳解

    C++ Boost PropertyTree解析INI文件詳解

    Boost PropertyTree庫(kù)不僅可以解析JSON,XML格式,還可以直接解析INI格式文件。這篇文章就是為大家介紹一下如何通過(guò)Boost PropertyTree解析INI文件,需要的可以參考一下
    2022-01-01
  • C++實(shí)現(xiàn)LeetCode(47.全排列之二)

    C++實(shí)現(xiàn)LeetCode(47.全排列之二)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(47.全排列之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 如何給隨機(jī)數(shù)加密

    如何給隨機(jī)數(shù)加密

    隨機(jī)數(shù)加密的簡(jiǎn)單算法,需要的朋友可以參考一下
    2013-03-03

最新評(píng)論