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

c++11封裝thread庫(kù)的方法示例

 更新時(shí)間:2019年01月29日 11:21:20   作者:chaozh.com  
C++11 ,封裝了thread的多線程的類,這樣對(duì)多線程的使用更加方便。下面這篇文章主要給大家介紹了關(guān)于c++11封裝thread庫(kù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

c++11在語(yǔ)言層面上提供了對(duì)thread的支持,由于不同的平臺(tái)提供了不同線程API,在語(yǔ)言層面提供了對(duì)thread的支持可以大大的減小代碼移植的工作量。

本文將給大家詳細(xì)介紹關(guān)于c++11封裝thread庫(kù)的相關(guān)內(nèi)容,下面話不多說了,來一起看看詳細(xì)的介紹吧

基本接口要求

要求std::thread的構(gòu)造函數(shù)

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

但是OS的庫(kù)函數(shù)定義為:

error_code create_thread((void_or_error_code(*entry)(void *), void *data);

主要是接口中的entry,本身使用void*根本沒帶類型信息,難點(diǎn)在于要做到模板暴露出類型從而可以通用化

void_or_error_code entry_point(void *arbitrary_data);

第一個(gè)問題:把f和args統(tǒng)統(tǒng)打包在一起做成一個(gè)void *結(jié)構(gòu)

我們得從void* 中獲取函數(shù)指針和參數(shù)指針,首先來個(gè)結(jié)構(gòu)體定義真實(shí)指針類型

struct thread_data_base
{
 virtual ~thread_data_base(){}
 virtual void run()=0;
};

需要一個(gè)tuple,用于保存f和args,這樣我們就可以通過將void *data cast成thread_data_base *,然后調(diào)用其中的虛函數(shù)run來實(shí)際調(diào)用f(args…)

std::tuple<typename std::decay<F>::type, typename std::decay<ArgTypes>::type...> fp;

而entry函數(shù)實(shí)現(xiàn)效果大致如下,將結(jié)構(gòu)體包裝在該函數(shù)里面

void_or_error_code thread_entry(void *data) {
 std::unique_ptr<thread_data_base> p((thread_data_base *)data);
 p->run();
 // return result of p->run() if error code is required
}

第二個(gè)問題:定義一個(gè)template,以適配不同類型的f和args

template<typename F, class... ArgTypes>
class thread_data : public thread_data_base
{
public:
 thread_data(F&& f_, ArgTypes&&... args_): fp(std::forward<F>(f_), std::forward<ArgTypes>(args_)...) {}
private:
 std::tuple<typename std::decay<F>::type, typename std::decay<ArgTypes>::type...> fp;
}

在這個(gè)template里有一個(gè)data member正是那個(gè)關(guān)鍵的tuple,其類型需要使用traits進(jìn)行類型推理出來

第三個(gè)問題:把任意的f和args包裝成一個(gè)thread_data_base *

定義創(chuàng)建函數(shù)可以將任意f和arg來創(chuàng)建一個(gè)void*結(jié)構(gòu)體,用來被entry函數(shù)調(diào)用

template<typename F, class... ArgTypes>
inline thread_data_base *make_thread_data(F&& f, ArgTypes&&... args)
{
 return new thread_data<typename std::remove_reference<F>::type, ArgTypes...>(std::forward<F>(f),
                   std::forward<ArgTypes>(args)...); // 啥時(shí)候釋放?
}

第四個(gè)問題:如何處理Args…

難點(diǎn)在于如何通過一個(gè)f和args組成的tuple調(diào)用f(args…),使用get需要傳入一個(gè)編譯期常量

tp.get<0>()(tp.get<1>(), tp.get<2>(), tp.get<3>());

為了方便,我們想把數(shù)列當(dāng)前項(xiàng)直接放在參數(shù)列表里,要不然還需要在內(nèi)部找到數(shù)列的最后一項(xiàng)

template <std::size_t Ep, std::size_t Sp>
struct make_tuple_indices {...};

為了生成數(shù)列[Sp, Ep),我們要做的就是從Sp開始,遞歸的在已有數(shù)列后面加一項(xiàng),直到滿足條件(Sp==Ep),下面就是最后定義的泛化,遞歸,終止條件

template <std::size_t Sp, class IntTuple, std::size_t Ep> struct make_indices_imp;

template <std::size_t Sp, std::size_t... Indices, std::size_t Ep>
struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep>
{ typedef typename make_indices_imp<Sp+1, tuple_indices<Indices..., Sp>, Ep>::type type; };

template <std::size_t Ep, std::size_t... Indices>
struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep>
{ typedef tuple_indices<Indices...> type; };

template <std::size_t Ep, std::size_t Sp=0>
struct make_tuple_indices {
 typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
};

已經(jīng)有了run,之所以需要再定義一個(gè)run2,Indices是一個(gè)template type,只能用一個(gè)template function接收,所以我們需要把run和run2拆開,run作為繼承下來的虛函數(shù)做入口,run2接收Indices并用之前提到的方法調(diào)用f(args…)。

實(shí)際上thread_data_base接口就是實(shí)現(xiàn)了一個(gè)簡(jiǎn)化版的std::bind

靜態(tài)檢查工具:Clang thread safety annotations,添加安全注解:通過代碼注解告訴編譯器哪些成員變量和成員函數(shù)是受哪個(gè) mutex 保護(hù),防止遺漏線程安全的假設(shè)。用 GUARDED_BY 表明哪個(gè)成員變量是被哪個(gè) mutex 保護(hù)的

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • C++深入探究二階構(gòu)造模式的原理與使用

    C++深入探究二階構(gòu)造模式的原理與使用

    C++中經(jīng)常會(huì)因?yàn)檎{(diào)用系統(tǒng)資源失敗導(dǎo)致出現(xiàn)BUG,所以在類調(diào)用構(gòu)造函數(shù)需要分配系統(tǒng)資源時(shí)會(huì)出現(xiàn)BUG,從而導(dǎo)致類對(duì)象雖然被創(chuàng)建,但是只是個(gè)半成品,為了避免這種情況需要使用二階構(gòu)造模式
    2022-04-04
  • C++11如何引入的尾置返回類型

    C++11如何引入的尾置返回類型

    C++11 標(biāo)準(zhǔn)引入的尾置返回類型,可以讓返回復(fù)雜類型的函數(shù)聲明更加清晰易讀,在無法使用C++14 標(biāo)準(zhǔn)的情況下,通過尾置返回類型的語(yǔ)法來推導(dǎo)函數(shù)模板的返回類型無疑是最簡(jiǎn)便的方法,這篇文章主要介紹了C++11引入的尾置返回類型,需要的朋友可以參考下
    2023-01-01
  • C語(yǔ)言中宏定義的妙用方法

    C語(yǔ)言中宏定義的妙用方法

    今天小編就為大家分享一篇關(guān)于C語(yǔ)言中宏定義的妙用方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 引用參數(shù)和傳值參數(shù)的區(qū)別深入解析

    引用參數(shù)和傳值參數(shù)的區(qū)別深入解析

    以下是對(duì)引用參數(shù)和傳值參數(shù)的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-07-07
  • 關(guān)于memcpy和memmove的一點(diǎn)重要說明

    關(guān)于memcpy和memmove的一點(diǎn)重要說明

    下面小編就為大家?guī)硪黄P(guān)于memcpy和memmove的一點(diǎn)重要說明。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • C++中求余運(yùn)算符(%)示例詳解

    C++中求余運(yùn)算符(%)示例詳解

    求余運(yùn)算符“%”,二元運(yùn)算符,具有左結(jié)合性。參與運(yùn)算的量均為整型。求余運(yùn)算的結(jié)果等于兩個(gè)數(shù)相除后的余數(shù)??此坪芎?jiǎn)單的運(yùn)算符,卻也真要掌握用好它也不容易,這篇文章主要介紹了C++中求余運(yùn)算符(%)的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • 淺談使用C++多級(jí)指針存儲(chǔ)海量qq號(hào)和密碼

    淺談使用C++多級(jí)指針存儲(chǔ)海量qq號(hào)和密碼

    這篇文章主要介紹了淺談使用C++多級(jí)指針存儲(chǔ)海量qq號(hào)和密碼,分享了相關(guān)實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • C語(yǔ)言與C++中const的用法對(duì)比

    C語(yǔ)言與C++中const的用法對(duì)比

    C語(yǔ)言中的const與C++有很大的不同,在C語(yǔ)言中用const修飾的變量仍是一個(gè)變量,表示這個(gè)變量是只讀的,不可顯示地更改,而在C++中用const修飾過后,就變成常量了
    2022-04-04
  • 通過GDB學(xué)習(xí)C語(yǔ)言的講解

    通過GDB學(xué)習(xí)C語(yǔ)言的講解

    今天小編就為大家分享一篇關(guān)于通過GDB學(xué)習(xí)C語(yǔ)言的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 淺談C#互操作的內(nèi)存溢出問題

    淺談C#互操作的內(nèi)存溢出問題

    以前了解過c++的棧內(nèi)存溢出,沒想到在c#里被我遇到了,問題看似不大,如何被恰好相鄰的四個(gè)字節(jié)是返回地址,說不定危害不小??!看來c#的互操作還是得小心為好
    2013-10-10

最新評(píng)論