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

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

近期看到有讀者在公眾號留言問有沒有C 多線程的學習方法,我這里特意總結了下,希望能對大家有所幫助。



目錄

  • 什么是多線程?

  • 為什么使用多線程?

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

  • joinable()?

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

  • 原子變量

  • 條件變量

  • async

  • 多線程周邊

  • 關于多線程的一些建議



什么是多線程?

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

為什么要用多線程?

不介紹,基礎知識,和上面在一個鏈接。



C 多線程知識點


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

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


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


至于std::jthread,不用管,學完std::thread后自然就能學會std::jthread。


關于C 11的多線程具體介紹可以看c 11新特性之線程相關所有知識點


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

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


因為如果不這么調用,在thread生命周期結束時,程序會crash。原因直接看thread的析構函數(shù):

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

join()和detach()?

上面介紹了不調用join,程序會crash,其實也可以調用detach來避免程序crash,那它倆有什么區(qū)別?


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


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


joinable()是什么?

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


參數(shù)傳遞問題

多線程其實就是開啟一個線程,運行某一個函數(shù),上面的示例是運行的無參函數(shù),那如何運行有參函數(shù)?怎么將參數(shù)傳遞進去?其實有好幾種方法傳遞參數(shù),我更傾向于使用的是lambda表達式,將有參函數(shù) 參數(shù)封裝成無參函數(shù),然后多線程調用。


示例代碼:

#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;}

關于lambda表達式我之前寫過文章介紹,可以看這里:


搞定c 11新特性std::function和lambda表達式

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


成員函數(shù)問題

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

#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;}


小知識點


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


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

有人在技術交流群里問過這兩種方式的區(qū)別,相信仔細閱讀過上面內容的你應該知道答案!

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

為什么需要鎖?

因為多線程讀寫數(shù)據(jù)可能存在線程安全問題,為了保證線程安全,其中一種方式就是使用鎖。

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

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


mutex有四種:

  • std::mutex:獨占的互斥量,不能遞歸使用,不帶超時功能

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

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

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


加解鎖方式有三種:

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

  • std::unique_lock:比lock_guard多了個手動加解鎖的功能

  • std::scoped_lock:防止多個鎖順序問題導致的死鎖問題而出世的一把鎖


示例代碼:

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

原子操作

上面介紹過使用鎖可以解決線程安全問題,其實簡單的變量,比如整型變量等,可以使用原子操作,C 11的原子操作都在中。


示例代碼:

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

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


條件變量

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


示例代碼:

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;};

有關條件變量其實有兩個坑需要注意,移步這里:使用條件變量的坑你知道嗎


基于任務的并發(fā)

這塊個人認為只需要了解async即可,通過async既可以達到并發(fā)的目的,也可以拿到并發(fā)執(zhí)行后的結果。


示例代碼:

#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新特性之線程相關所有知識點


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


其他


如何使線程休眠?


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

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

線程個數(shù)問題


很多人都會糾結線程池開多少個線程效率最高的問題,假設CPU個數(shù)為N,有的資料會介紹N個線程效率最高,有的資料會介紹2N個線程效率最高。在中通過以下函數(shù)可以獲取CPU的個數(shù):

static unsigned hardware_concurrency() noexcept;

至于需要開多少個線程,個人認為需要根據(jù)個性化需求實際測試,你測出來多少個線程性能最高,就開多少個線程。


死鎖

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

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


我關于多線程還有一些建議,推薦大家看這個:


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


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





手擼一個對象池


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


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


從未見過把內存玩的如此明白的文章(推薦大家都來看看)


寫出高效代碼的12條建議


推薦幾個開源庫



分享

收藏

點贊

在看


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

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

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

關鍵字: 汽車 人工智能 智能驅動 BSP

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

關鍵字: 亞馬遜 解密 控制平面 BSP

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

關鍵字: 騰訊 編碼器 CPU

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

關鍵字: 華為 12nm EDA 半導體

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

關鍵字: 華為 12nm 手機 衛(wèi)星通信

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

關鍵字: 通信 BSP 電信運營商 數(shù)字經濟

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

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

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

關鍵字: BSP 信息技術
關閉
關閉