日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++11 多线程

發(fā)布時(shí)間:2024/4/17 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++11 多线程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線程的創(chuàng)建

#include<thread>

void func(){}

std::thread t(func);

Join函數(shù)將會阻塞線程,直到線程函數(shù)執(zhí)行結(jié)束。如果不希望線程被阻塞執(zhí)行,可以調(diào)用線程的detach()方法,將線程和對象分離,當(dāng)前線程不會阻塞。

線程不能賦值,但是可以移動;

std::thread t(func);

std::thread t1(std::move(t));

線程對象t將不再不代表任何線程。

注意線程對象的聲明周期,確保函數(shù)執(zhí)行的過程中,thread的對象仍然是存在的。可以使用join或者detach。

線程的基本使用方法

獲取線程的id和cpu的核心

std::thread t(func);

t.get_id()--------->線程的id

std::thread::hardware_concurrency()---->cpu的核心數(shù)

線程休眠

std::this_thead::sleep_for(std::chrono::seconds(3));

線程互斥量

std::mutex:獨(dú)占的互斥量,不能遞歸使用

std::timed_mutex:帶超時(shí)的獨(dú)占互斥量,不能遞歸使用

std::recursive_mutex:遞歸互斥量,不帶超時(shí)

std::recursive_timed_mutex:帶超時(shí)的遞歸互斥量

1.std::mutex

std::mutex g_lock;

g_lock.lock();

..............

g_lock.unlock();

{

std::lock_guard<std::mutex> lg(g_lock);

}

2.遞歸獨(dú)占互斥量std::recursive_mutex

遞歸互斥量運(yùn)行同一個(gè)線程多次獲得該互斥鎖,用來解決同一線程需要多次獲取互斥量時(shí)的死鎖問題。

3.帶有超時(shí)互斥量std::timed_mutex和std::recusive_timed_mutex

std:teime_mutex比std::mutex多了兩個(gè)接口:try_lock_for和try_lock_until

if(mutex.try_lock_for(timeout)

條件變量

conditon_variable,配合std::unique_lock<std::mutex> 進(jìn)行wait操作。

condition_variable_any,和任意帶有l(wèi)ock、unlock語義的mutex搭配使用,效率比conditional_variable差很多。

1)擁有條件變量的線程獲取互斥量

2)循環(huán)檢查某個(gè)條件,如果條件不滿足,則阻塞直到條件滿足;如果滿足,繼續(xù)執(zhí)行。

3)某個(gè)線程滿足條件執(zhí)行完后調(diào)用notify_one或notify_all喚醒一個(gè)或者所有的等待線程。

std::lock_guard<std::mutex> locker(m_mutex);

while(IsFull())

? ? ? ? ? ? ? ?m_notFull.wait(m_mutex);

m_notEmpty.notify_one();

wait還可以接受條件:

m_notFull.wait(locker,[this]{return !IsFull()});

wait的時(shí)候會釋放鎖,但是notify,notifyall的時(shí)候會獲取鎖。

std::unique_lock它可以隨時(shí)釋放鎖。

std::unque_lock<std::mutex> locker(m_mutex);

m_notEmpty.wait(locker,[this]{return !m_queue.empty();});

?

原子量

std::atomic<int> value;

?

call_once/once_flag的使用

call_once確保在多線程情況下,被調(diào)用一次。

std::once_flag flag;

void do_once(){

? std::call_once(flag,[](){std::cout<<"Called once");

}

異步操作

std::future->作為異步結(jié)果的傳輸通道;

std::promise->將數(shù)據(jù)和future綁定起來,方便線程賦值。

std::package_task用來包裝一個(gè)可調(diào)用對象,將函數(shù)和future綁定起來,方便異步調(diào)用。

std:future

獲取線程的指向結(jié)果,通過查詢future的狀態(tài)來獲取異步操作的結(jié)果。future只能move不能拷貝,如果放到容器,必須使用shared_future

future_status有如下的3種狀態(tài):

1.deferred,異步還沒有開始

2.Ready,異步操作已經(jīng)完成

3.Timeout,異步操作超時(shí)

status =future_wait_for(std::chrono::seconds(1));

std::future_status status;

std::promise

std::promise<int> pr;

std::thread t([](std::promise<int>& p){p.set_value_at_thread_exit(9);}, std::ref(pr));

std::future<int> f=pr.get_future();

auto r=f.get();

std::package_task

包裝了一個(gè)可調(diào)用對象的包裝類(如function/lambda/bind),將函數(shù)和future綁定,以便異步調(diào)用,promise保存了一個(gè)共享狀態(tài)的值。

std::packaged_task<int()> task([](){return 7});

std::thread t1(std::ref(task));

std::futrue<int> f1=task.get_future();

auto r1=f1.get();

線程異步操作函數(shù)async

std::async比std::promise更高一層,異步任務(wù)返回的結(jié)果保存在future中,當(dāng)需要獲取異步任務(wù)的是,需要調(diào)用future.get(),如果僅僅等待執(zhí)行完成,調(diào)用future.wait

有兩種策略:

std::launch::async:調(diào)用async的時(shí)候開始創(chuàng)建線程

std::launch::defered:延遲加載方式線程,調(diào)用async時(shí)不創(chuàng)建線程,直到線程get或者wait時(shí)才創(chuàng)建線程。

?

std::future<int> f1=std::async(std::launch::async,[](){});

?

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的c++11 多线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。