www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序喵大人
[導(dǎo)讀]近期看到有讀者在公眾號(hào)留言問(wèn)有沒(méi)有C多線程的學(xué)習(xí)方法,我這里特意總結(jié)了下,希望能對(duì)大家有所幫助。目錄什么是多線程?為什么使用多線程?如何創(chuàng)建線程?joinable()?多線程參數(shù)傳遞方式鎖原子變量條件變量async多線程周邊關(guān)于多線程的一些建議什么是多線程?不介紹,基礎(chǔ)知識(shí),直接...

近期看到有讀者在公眾號(hào)留言問(wèn)有沒(méi)有C 多線程的學(xué)習(xí)方法,我這里特意總結(jié)了下,希望能對(duì)大家有所幫助。



目錄

  • 什么是多線程?

  • 為什么使用多線程?

  • 如何創(chuàng)建線程?

  • joinable()?

  • 多線程參數(shù)傳遞方式

  • 原子變量

  • 條件變量

  • async

  • 多線程周邊

  • 關(guān)于多線程的一些建議



什么是多線程?

不介紹,基礎(chǔ)知識(shí),直接看維基百科:https://zh.wikipedia.org/wiki/多線程

為什么要用多線程?

不介紹,基礎(chǔ)知識(shí),和上面在一個(gè)鏈接。



C 多線程知識(shí)點(diǎn)


如何創(chuàng)建線程?

多線程有多種創(chuàng)建方式:pthread、std::thread、std::jthread。


這里我推薦學(xué)習(xí)C 11引入的std::thread,它較pthread更方便,且在C 中更加常用。


至于std::jthread,不用管,學(xué)完std::thread后自然就能學(xué)會(huì)std::jthread。


關(guān)于C 11的多線程具體介紹可以看c 11新特性之線程相關(guān)所有知識(shí)點(diǎn)


使用std::thread創(chuàng)建線程很簡(jiǎn)單,直接利用它的構(gòu)造函數(shù)即可:

void func() { xxxx;}
int main() { std::thread t(func); if (t.joinable()) { t.join(); } return 0;}注意上面代碼,我使用了一個(gè)joinable()和join(),為什么要這么做?


因?yàn)槿绻贿@么調(diào)用,在thread生命周期結(jié)束時(shí),程序會(huì)crash。原因直接看thread的析構(gòu)函數(shù):

~thread(){ if (joinable()) std::terminate();}

join()和detach()?

上面介紹了不調(diào)用join,程序會(huì)crash,其實(shí)也可以調(diào)用detach來(lái)避免程序crash,那它倆有什么區(qū)別?


join()表示阻塞等待子線程執(zhí)行結(jié)束,子線程結(jié)束后才會(huì)繼續(xù)往下執(zhí)行。


detach()表示與當(dāng)前對(duì)象分離,子線程無(wú)論做啥,無(wú)論是否執(zhí)行結(jié)束都與我無(wú)關(guān),愛(ài)咋咋地,最終靠操作系統(tǒng)回收相關(guān)資源。


joinable()是什么?

上面代碼中出現(xiàn)了joinable(),可以簡(jiǎn)單理解為如果沒(méi)有調(diào)用join()或者detach(),joinable()就返回true。如果調(diào)用了其中一個(gè),joinable()就返回false。它主要就是為了搭配join()和detach()使用。


參數(shù)傳遞問(wèn)題

多線程其實(shí)就是開(kāi)啟一個(gè)線程,運(yùn)行某一個(gè)函數(shù),上面的示例是運(yùn)行的無(wú)參函數(shù),那如何運(yùn)行有參函數(shù)?怎么將參數(shù)傳遞進(jìn)去?其實(shí)有好幾種方法傳遞參數(shù),我更傾向于使用的是lambda表達(dá)式,將有參函數(shù) 參數(shù)封裝成無(wú)參函數(shù),然后多線程調(diào)用。


示例代碼:

#include #include
void func(int a, int b) { std::cout << "a b = " << a b << std::endl; }
int main() { auto lambda = []() { func(1, 2); }; std::thread t(lambda); if (t.joinable()) { t.join(); } return 0;}

關(guān)于lambda表達(dá)式我之前寫(xiě)過(guò)文章介紹,可以看這里:


搞定c 11新特性std::function和lambda表達(dá)式

編譯器如何實(shí)現(xiàn)lambda表達(dá)式?


成員函數(shù)問(wèn)題

很多人可能還有疑問(wèn),如果多線程運(yùn)行類(lèi)對(duì)象的成員函數(shù),這里可以使用和上面相同的方法,lambda表達(dá)式:

#include #include #include
struct A { void Print() { std::cout << "A\n"; }};
int main() { std::shared_ptr a = std::make_shared(); auto func = [a]() { a->Print(); }; std::thread t(func); if (t.joinable()) { t.join(); } return 0;}


小知識(shí)點(diǎn)


創(chuàng)建thread對(duì)象的常見(jiàn)方法有下面這兩種:


std::thread a(func);
std::thread *a = new thread(func);delete a;

有人在技術(shù)交流群里問(wèn)過(guò)這兩種方式的區(qū)別,相信仔細(xì)閱讀過(guò)上面內(nèi)容的你應(yīng)該知道答案!

給個(gè)小提示:兩者對(duì)象一個(gè)在堆上,一個(gè)在棧上,生命周期不同,即thread的析構(gòu)函數(shù)調(diào)用時(shí)機(jī)不同,然后可以再結(jié)合上面介紹的~thread()的實(shí)現(xiàn),思考一下。

為什么需要鎖?

因?yàn)槎嗑€程讀寫(xiě)數(shù)據(jù)可能存在線程安全問(wèn)題,為了保證線程安全,其中一種方式就是使用鎖。

關(guān)于線程安全問(wèn)題,隨便去個(gè)網(wǎng)站,比如維基百科、百度百科等,都能找到。

https://zh.wikipedia.org/wiki/線程安全


mutex有四種:

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

  • std::recursive_mutex:遞歸互斥量,可重入,不帶超時(shí)功能

  • std::timed_mutex:帶超時(shí)的互斥量,不能遞歸

  • std::recursive_timed_mutex:帶超時(shí)的互斥量,可以遞歸使用


加解鎖方式有三種:

  • std::lock_guard:可以RAII方式加鎖

  • std::unique_lock:比lock_guard多了個(gè)手動(dòng)加解鎖的功能

  • std::scoped_lock:防止多個(gè)鎖順序問(wèn)題導(dǎo)致的死鎖問(wèn)題而出世的一把鎖


示例代碼:

std::mutex?mutex; void?func()?{ std::lock_guard lock(mutex); xxxxxxx}

原子操作

上面介紹過(guò)使用鎖可以解決線程安全問(wèn)題,其實(shí)簡(jiǎn)單的變量,比如整型變量等,可以使用原子操作,C 11的原子操作都在中。


示例代碼:

std::atomic<int> count;
int get() { count.load();}
void set(int c) { count.store(c);}

上面這兩個(gè)函數(shù)可以在多線程中任意調(diào)用,不會(huì)出現(xiàn)線程安全問(wèn)題。


條件變量

條件變量是一種同步機(jī)制,可以阻塞一個(gè)線程或多個(gè)線程,直到其他線程對(duì)這些線程通知才會(huì)解除阻塞。這種通知和阻塞就需要用到條件變量。


示例代碼:

class CountDownLatch { public: explicit CountDownLatch(uint32_t count) : count_(count);
void CountDown() { std::unique_lock lock(mutex_); --count_; if (count_ == 0) { cv_.notify_all(); } }
void Await(uint32_t time_ms = 0) { std::unique_lock lock(mutex_); while (count_ > 0) { if (time_ms > 0) { cv_.wait_for(lock, std::chrono::milliseconds(time_ms)); } else { cv_.wait(lock); } } }
uint32_t GetCount() const { std::unique_lock lock(mutex_); return count_; }
private: std::condition_variable cv_; mutable std::mutex mutex_; uint32_t count_ = 0;};

有關(guān)條件變量其實(shí)有兩個(gè)坑需要注意,移步這里:使用條件變量的坑你知道嗎


基于任務(wù)的并發(fā)

這塊個(gè)人認(rèn)為只需要了解async即可,通過(guò)async既可以達(dá)到并發(fā)的目的,也可以拿到并發(fā)執(zhí)行后的結(jié)果。


示例代碼:

#include #include #include #include
using namespace std;
int func(int in) { return in 1; }
int main() { auto res = std::async(func, 5); cout << res.get() << endl; // 阻塞直到函數(shù)返回 return 0;}

具體可以看:c 11新特性之線程相關(guān)所有知識(shí)點(diǎn)


也可以看我利用此種方式寫(xiě)的線程池:C 11線程池


其他


如何使線程休眠?


可以利用std::this_thread和chrono,它倆搭配使得線程休眠很方便,而且休眠時(shí)間也很清晰??刹幌馛語(yǔ)言的sleep,我每次使用C語(yǔ)言的sleep時(shí)都會(huì)特意去搜索一下,單位究竟是秒還是毫秒。

std::this_thread::sleep_for(std::chrono::milliseconds(10));

線程個(gè)數(shù)問(wèn)題


很多人都會(huì)糾結(jié)線程池開(kāi)多少個(gè)線程效率最高的問(wèn)題,假設(shè)CPU個(gè)數(shù)為N,有的資料會(huì)介紹N個(gè)線程效率最高,有的資料會(huì)介紹2N個(gè)線程效率最高。在中通過(guò)以下函數(shù)可以獲取CPU的個(gè)數(shù):

static unsigned hardware_concurrency() noexcept;

至于需要開(kāi)多少個(gè)線程,個(gè)人認(rèn)為需要根據(jù)個(gè)性化需求實(shí)際測(cè)試,你測(cè)出來(lái)多少個(gè)線程性能最高,就開(kāi)多少個(gè)線程。


死鎖

死鎖的定義可直接維基百科:https://zh.wikipedia.org/wiki/死鎖

至于如何解決死鎖,可以看:多線程中如何使用gdb精確定位死鎖問(wèn)題


我關(guān)于多線程還有一些建議,推薦大家看這個(gè):


最后,在我學(xué)習(xí)多線程的過(guò)程中,發(fā)現(xiàn)了一篇介紹C 11多線程非常詳細(xì)的博客,也推薦大家看看。


博客鏈接:https://www.cnblogs.com/haippy/p/3284540.html





手?jǐn)]一個(gè)對(duì)象池


這里收集了100多篇C 原創(chuàng)文章(入門(mén)進(jìn)階必備)


if-else和switch-case哪個(gè)效率更高?看這四張圖。


從未見(jiàn)過(guò)把內(nèi)存玩的如此明白的文章(推薦大家都來(lái)看看)


寫(xiě)出高效代碼的12條建議


推薦幾個(gè)開(kāi)源庫(kù)



分享

收藏

點(diǎn)贊

在看


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉