中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

上海網(wǎng)站設(shè)計聯(lián)系方式在線視頻觀看免費視頻22

上海網(wǎng)站設(shè)計聯(lián)系方式,在線視頻觀看免費視頻22,wordpress用戶分組,廣西建設(shè)工程信息網(wǎng)官網(wǎng)《c并發(fā)編程實戰(zhàn)》 筆記 1、你好,C的并發(fā)世界為什么要使用并發(fā) 第2章 線程管理2.1.1 啟動線程2.2 向線程函數(shù)傳遞參數(shù)2.5 識別線程 第3章 線程間共享數(shù)據(jù)3.2.1 C中使用互斥量避免死鎖的進階指導(dǎo)保護共享數(shù)據(jù)的替代設(shè)施 第4章 同步并發(fā)操作4.1 等待一個事件或其他條件…

《c++并發(fā)編程實戰(zhàn)》 筆記

  • 1、你好,C++的并發(fā)世界
    • 為什么要使用并發(fā)
  • 第2章 線程管理
    • 2.1.1 啟動線程
    • 2.2 向線程函數(shù)傳遞參數(shù)
    • 2.5 識別線程
  • 第3章 線程間共享數(shù)據(jù)
    • 3.2.1 C++中使用互斥量
    • 避免死鎖的進階指導(dǎo)
    • 保護共享數(shù)據(jù)的替代設(shè)施
  • 第4章 同步并發(fā)操作
    • 4.1 等待一個事件或其他條件
    • 4.2 使用期望等待一次性事件
  • 第6章 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計
    • 4.2 使用期望等待一次性事件

1、你好,C++的并發(fā)世界

為什么要使用并發(fā)

1、并發(fā)分離關(guān)注點的定義
并發(fā)分離關(guān)注點主要是指在并發(fā)編程中,通過將不同的邏輯或任務(wù)分離到不同的線程或進程中執(zhí)行,從而實現(xiàn)關(guān)注點(即程序中需要特別關(guān)注或處理的部分)的分離。這種分離有助于簡化程序結(jié)構(gòu),提高代碼的可讀性和可維護性。

2、使用并發(fā)提高性能,可用的方法

  1. 第一個也是最明顯的是將單個任務(wù)劃分為多個部分并并行運行每個部分,從而減少總運行時間。
  2. 第二個:數(shù)據(jù)并行性(Data Parallelism),即同時對多個數(shù)據(jù)集或數(shù)據(jù)塊執(zhí)行相同的操作或算法。

初始線程始于main(),而新線程始于hello()。

第2章 線程管理

2.1.1 啟動線程

使用C++線程庫啟動線程,可以歸結(jié)為構(gòu)造std::thread對象:

std::thread

template< class Function, class... Args >  
explicit thread( Function&& f, Args&&... args );
  • Function 是一個可調(diào)用對象(如函數(shù)指針、lambda 表達(dá)式、函數(shù)對象等)的類型。
  • Args… 是傳遞給 Function的參數(shù)的類型列表。

std::thread 在 C++ 中扮演著核心角色,特別是在多線程編程領(lǐng)域。它的主要作用是提供一種機制來創(chuàng)建和管理線程,使得程序能夠并行地執(zhí)行多個任務(wù)。

  • 創(chuàng)建新線程:通過 std::thread的構(gòu)造函數(shù),可以輕松地創(chuàng)建一個新線程來執(zhí)行指定的函數(shù)或可調(diào)用對象。這允許開發(fā)者將耗時的操作或可以并行處理的任務(wù)放到單獨的線程中執(zhí)行,從而提高程序的性能和響應(yīng)性。
  • 管理線程生命周期:std::thread 對象與它所代表的線程緊密相關(guān)。通過調(diào)用 join() 或 detach()方法,可以管理線程的生命周期。join() 方法會阻塞當(dāng)前線程,直到由 std::thread 對象表示的線程完成其執(zhí)行。detach()方法則允許線程獨立于 std::thread 對象運行,此時 std::thread對象不再擁有該線程,且無法再與之交互(除了獲取其ID)。

線程可連接(joinable)是C++中std::thread對象的一個狀態(tài),它表示該std::thread對象代表了一個正在運行或已經(jīng)啟動但尚未結(jié)束的線程。當(dāng)一個std::thread對象被創(chuàng)建并成功啟動了一個新線程時,它就進入了可連接狀態(tài)。

線程資源:
如線程棧、線程控制塊等。如果這些資源在std::thread對象被銷毀時仍未被釋放,就會發(fā)生資源泄露。
在C++中,std::thread對象通過join()或detach()方法來管理其代表的線程。如果std::thread對象在銷毀時仍然是可連接的(即線程仍在運行),且既未調(diào)用join()也未調(diào)用detach(),則程序會調(diào)用std::terminate()來終止執(zhí)行,以防止?jié)撛诘馁Y源泄露。
std::terminate會終止整個程序,而不是線程。操作系統(tǒng)會在程序終止時回收所有由該程序分配的資源。為了防止程序在不確定的線程狀態(tài)下繼續(xù)執(zhí)行,因為此時線程可能還在訪問或操作已經(jīng)銷毀的 std::thread 對象所管理的資源。

std::thread對象通常與特定的執(zhí)行線程相關(guān)聯(lián),并且一旦線程執(zhí)行完畢,std::thread對象就不再擁有任何線程(即變?yōu)榭?#xff09;。

線程的狀態(tài)變化:

  • 從非joinable到j(luò)oinable:

    • 當(dāng)通過調(diào)用std::thread的構(gòu)造函數(shù)并傳入一個可調(diào)用對象(如函數(shù)指針、Lambda表達(dá)式、綁定表達(dá)式等)來創(chuàng)建std::thread對象時,如果構(gòu)造函數(shù)成功,則新創(chuàng)建的線程對象將處于joinable狀態(tài)。這意呀著你可以對該線程調(diào)用join()來等待它完成,或者調(diào)用detach()來分離它。
  • 從joinable到非joinable:

    • 一旦對joinable的線程調(diào)用了join()或detach(),該線程對象就不再處于joinable狀態(tài)。對已經(jīng)join或detach的線程對象再次調(diào)用join()或detach()將導(dǎo)致std::system_error異常。
    • 如果線程的執(zhí)行函數(shù)已經(jīng)返回(即線程已結(jié)束),并且你尚未對該線程調(diào)用join()或detach(),則嘗試對該線程對象調(diào)用join(),detach仍然有效,但調(diào)用后將使線程對象變?yōu)榉莏oinable。
    • 如果線程對象被銷毀時仍然處于joinable狀態(tài)(即沒有調(diào)用join()或detach()),則程序?qū)⒄{(diào)用std::terminate()來終止執(zhí)行,以避免資源泄露。因此,重要的是要確保在銷毀std::thread對象之前,要么調(diào)用join()要么調(diào)用detach()。

2.2 向線程函數(shù)傳遞參數(shù)

參數(shù)要拷貝到線程獨立內(nèi)存中,即使參數(shù)是引用的形式,也可以在新線程中進行訪問。

一定要使用引用:
std::ref 用于創(chuàng)建一個對給定對象的引用封裝器(reference wrapper),這個封裝器可以被存儲在容器中,或者作為函數(shù)參數(shù)傳遞給需要復(fù)制語義但實際上需要引用語義的地方。簡而言之,std::ref 允許你以引用的方式傳遞對象,即使是在需要拷貝的上下文中。

std::bind 是 C++ 標(biāo)準(zhǔn)庫中的一個功能強大的工具,它定義在頭文件 中。std::bind 用于將可調(diào)用對象(如函數(shù)、函數(shù)對象、lambda 表達(dá)式、成員函數(shù)指針等)與其參數(shù)綁定在一起,生成一個新的可調(diào)用對象。這個新的可調(diào)用對象在調(diào)用時,會調(diào)用原始的可調(diào)用對象,并傳遞給它預(yù)先綁定的參數(shù)(如果有的話),以及調(diào)用新可調(diào)用對象時提供的任何額外參數(shù)。

2.5 識別線程

2種方法

  • 第一種,可以通過調(diào)用std::thread對象的成員函數(shù)get_id()來直接獲取。如果std::thread對象沒有與任何執(zhí)行線程相關(guān)聯(lián),get_id()將返回std::thread::type默認(rèn)構(gòu)造值,這個值表示“沒有線程”。
  • 第二種,當(dāng)前線程中調(diào)用std::this_thread::get_id()(這個函數(shù)定義在頭文件中)也可以獲得線程標(biāo)識。

第3章 線程間共享數(shù)據(jù)

3.2.1 C++中使用互斥量

C++中通過實例化std::mutex創(chuàng)建互斥量,通過調(diào)用成員函數(shù)lock()進行上鎖,unlock()進行解鎖。實踐中更推薦使用RAII語法的模板類std::lock_guard。

加了鎖之后,還需要注意:被保護量不會通過指針或引用方式傳遞到外部去。

避免死鎖的進階指導(dǎo)

死鎖定義:它指的是兩個或多個線程在執(zhí)行過程中,因爭奪資源而造成的一種僵局(互相等待)。

避免死鎖的方法:

  1. 避免使用多個鎖
  2. 保持鎖的順序一致
  3. 避免嵌套鎖
  4. 使用超時機制
  5. 使用標(biāo)準(zhǔn)庫中的工具
    C++標(biāo)準(zhǔn)庫提供了一些工具來幫助避免死鎖,如std::lock和std::scoped_lock。
    std::lock可以一次性為多個互斥量上鎖,并且內(nèi)部使用死鎖避免算法。
    std::lock_guard RAII(Resource Acquisition Is Initialization)原則,這意味著資源的獲取(在這里是互斥量的加鎖)是在對象的構(gòu)造函數(shù)中完成的,而資源的釋放(在這里是互斥量的解鎖)則是在對象的析構(gòu)函數(shù)中完成的。
    std::scoped_lock是一種RAII(Resource Acquisition Is Initialization)風(fēng)格的鎖管理器,它可以在構(gòu)造時自動上鎖,并在析構(gòu)時自動解鎖,從而簡化了鎖的管理。對多個鎖進行操作,C++ 17引入。
    std::unique_lock提供了比 std::lock_guard 更加靈活的互斥量封裝。std::unique_lock 提供了更多的控制,包括延遲加鎖、嘗試加鎖、定時加鎖以及手動解鎖和重新加鎖的能力。
  6. 持有鎖的時間盡可能少,減少死鎖概率。

保護共享數(shù)據(jù)的替代設(shè)施

保護共享數(shù)據(jù)的初始化過程

雙重檢查鎖存在的問題:
由于C++11之前的內(nèi)存模型并沒有提供足夠的保證來防止指令重排序,因此在多線程環(huán)境中使用雙重檢查鎖模式可能會導(dǎo)致未定義行為,比如訪問未完全初始化的對象。

std::call_once 是 C++11 引入的一個函數(shù),它屬于 頭文件。這個函數(shù)的主要用途是確保某個函數(shù)或可調(diào)用對象只被執(zhí)行一次,即使它被多次調(diào)用。這對于初始化全局變量或執(zhí)行只需要執(zhí)行一次的昂貴操作特別有用。

std::call_once 的使用通常與 std::once_flag 類型的標(biāo)志一起,這個標(biāo)志用來指示函數(shù)是否已經(jīng)被調(diào)用過。如果函數(shù)已經(jīng)被調(diào)用,那么后續(xù)的調(diào)用將不會執(zhí)行任何操作。

在C++11標(biāo)準(zhǔn)中,靜態(tài)局部變量即便在多線程中,也只被初始化一次。

保護很少更新的數(shù)據(jù)結(jié)構(gòu)(讀多寫少)
boost::shared_mutex 是 Boost 庫中的一個同步原語,它允許多個線程以共享模式(shared mode)同時讀取數(shù)據(jù),但寫入數(shù)據(jù)時需要獨占訪問。
使用 boost::shared_lockboost::shared_mutex 來獲取共享鎖。
使用 std::unique_lockboost::shared_mutex 來獲取獨占鎖。
本質(zhì)和讀寫鎖類似。

嵌套鎖
std::recursive_mutex,支持一個線程嘗試鎖多次。適用于獲取鎖的時候用到了其他函數(shù),其他函數(shù)也訪問這個鎖。
更好的替代方法是:考慮是否可以重新設(shè)計函數(shù)邏輯,避免遞歸調(diào)用,從而無需使用遞歸互斥鎖。

第4章 同步并發(fā)操作

線程會等待一個特定事件的發(fā)生,或者等待某一條件達(dá)成(為true)。像這種情況就需要在線程中進行同步,C++標(biāo)準(zhǔn)庫提供了一些工具可用于同步操作,形式上表現(xiàn)為條件變量(condition variables)和期望(futures)。

4.1 等待一個事件或其他條件

條件變量:condition_variable
是利用線程間共享的變量進行同步的一種機制。在多線程程序中,條件變量常用于實現(xiàn)“等待–>喚醒”邏輯,用于維護一個條件(注意區(qū)分條件變量與條件本身),線程可以使用條件變量來等待某個條件為真。
常與鎖結(jié)合。

條件變量的基本原理包括兩個主要動作:
等待:當(dāng)某個條件不滿足時,一個線程會將自己加入等待隊列,并釋放持有的互斥鎖(Mutex),進入睡眠狀態(tài)等待條件成立。wait函數(shù),需要帶條件,可能虛假喚醒。
喚醒:當(dāng)條件滿足時,另一個線程會通知(signal或broadcast)等待在條件變量上的線程,喚醒它們重新檢查條件。被喚醒的線程會重新嘗試獲取互斥鎖,并在獲取鎖后繼續(xù)執(zhí)行。notify_one()與notify_all()。

4.2 使用期望等待一次性事件

std::future
獲得一個 std::future 對象,這個對象將在未來某個時間點持有異步操作的結(jié)果。
關(guān)鍵函數(shù):

  • get():這個函數(shù)阻塞當(dāng)前線程,直到異步操作完成,并返回操作的結(jié)果。如果異步操作拋出了異常,get()
    函數(shù)將重新拋出該異常。注意,get() 只能被調(diào)用一次,因為一旦結(jié)果被取出,std::future 對象就不再持有任何結(jié)果了。
  • wait():這個函數(shù)也會阻塞當(dāng)前線程,但它只是等待異步操作完成,而不返回結(jié)果。如果只是想等待異步操作完成而不關(guān)心結(jié)果,可以使用這個函數(shù)。
  • wait_for() 和wait_until():這兩個函數(shù)提供了更靈活的等待機制。它們允許你指定一個時間段或時間點,然后在這個時間段內(nèi)等待異步操作完成。如果操作在這段時間內(nèi)完成了,函數(shù)將返回std::future_status::ready;如果操作沒有完成,函數(shù)將返回 std::future_status::timeout或 std::future_status::deferred(對于 std::async 啟動的異步任務(wù),后者幾乎不會出現(xiàn))。
  • valid():這個函數(shù)檢查 std::future 對象是否還持有有效的異步操作結(jié)果。一旦 get()被調(diào)用或異步操作被取消,valid() 將返回 false。

std::async
是 C++11 標(biāo)準(zhǔn)庫中的一個函數(shù)模板,它提供了一種方便的方式來啟動一個異步任務(wù)。當(dāng)你調(diào)用 std::async 時,你可以指定要執(zhí)行的函數(shù)(或可調(diào)用對象)、傳遞給該函數(shù)的參數(shù),以及一個啟動策略(可選)。std::async 返回一個 std::future 對象,這個對象將在未來某個時間點持有異步操作的結(jié)果。
啟動策略:

  • std::launch::async:指示 std::async 應(yīng)該異步地執(zhí)行函數(shù),即在新線程或線程池中執(zhí)行。如果系統(tǒng)無法立即啟動新線程,則行為是未定義的(盡管在實際的 C++ 實現(xiàn)中,它通常會阻塞直到能夠啟動新線程)。
  • std::launch::deferred:指示 std::async 應(yīng)該延遲執(zhí)行函數(shù),直到調(diào)用返回的 std::future 對象的 wait() 或 get() 方法。此時,函數(shù)將在調(diào)用這些方法的線程中同步執(zhí)行。
    如果省略啟動策略,則 std::async 可能會選擇 std::launch::async 或 std::launch::deferred,或者在某些情況下甚至可能使用混合策略。然而,這種混合模式的使用是不確定的,因此最好明確指定你想要的啟動策略。

std::packaged_task<>
是 C++11 標(biāo)準(zhǔn)庫中提供的一個模板類,它封裝了一個可調(diào)用對象(如函數(shù)、lambda 表達(dá)式、綁定表達(dá)式等),使得這個可調(diào)用對象可以異步執(zhí)行。可以通過調(diào)用 std::packaged_task<> 的 operator() 來異步地執(zhí)行封裝的可調(diào)用對象(比std::async更靈活)。

使用std::promises
是 C++11 標(biāo)準(zhǔn)庫中提供的一個類模板,它用于在異步編程中設(shè)置值或異常,以便與 std::future 對象共享這些值或異常。std::promise 和 std::future 一起工作,以支持跨線程的值傳遞和異常傳播。

主要函數(shù):

  • get_future(): 返回與 std::promise 對象關(guān)聯(lián)的 std::future 對象。這個函數(shù)只能被調(diào)用一次。
  • set_value(T value): 設(shè)置 std::promise 對象的值。這個函數(shù)只能被調(diào)用一次,并且只能在std::promise 對象被銷毀之前調(diào)用。
  • set_exception(std::exception_ptr p): 設(shè)置std::promise 對象的異常。這個函數(shù)也只能被調(diào)用一次,并且只能在 std::promise 對象被銷毀之前調(diào)用。

多個線程的等待同一個事件
使用std::shared_future::wait,std::shared_future 與 std::future 類似,但主要區(qū)別在于 std::shared_future 可以被多個線程或?qū)ο蠊蚕?#xff0c;而 std::future 一旦被移動或拷貝后,原始對象將不再持有任何結(jié)果,變成空狀態(tài)。

第6章 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計

4.2 使用期望等待一次性事件

http://www.risenshineclean.com/news/51201.html

相關(guān)文章:

  • 設(shè)計師個人網(wǎng)站模板湖州網(wǎng)站seo
  • 新疆網(wǎng)站建設(shè)咨詢谷歌paypal官網(wǎng)
  • 男女做那個網(wǎng)站動態(tài)圖片優(yōu)化設(shè)計七年級上冊語文答案
  • 行業(yè)信息網(wǎng)站建設(shè)方案房地產(chǎn)網(wǎng)站建設(shè)
  • 深圳網(wǎng)站建設(shè)php廈門seo全網(wǎng)營銷
  • 寧波seo整站優(yōu)化最新國際新聞50條簡短
  • 請人做網(wǎng)站誰來維護網(wǎng)站關(guān)鍵詞優(yōu)化怎么弄
  • 哪里查網(wǎng)站備案信息企業(yè)員工培訓(xùn)課程有哪些
  • 做網(wǎng)站平臺的營業(yè)執(zhí)照互聯(lián)網(wǎng)廣告推廣好做嗎
  • 廣州個人網(wǎng)站制作公司網(wǎng)絡(luò)推廣方案
  • 香港公司需要網(wǎng)站備案朋友圈廣告推廣平臺
  • 在百度上做網(wǎng)站推廣神器
  • 有關(guān)互聯(lián)網(wǎng)網(wǎng)站在線查詢網(wǎng)站收錄
  • dw網(wǎng)站二級頁面怎么做搜索引擎算法
  • 購買的網(wǎng)站如何換背景淘寶代運營靠譜嗎
  • 宜春seo網(wǎng)站推廣免費友情鏈接交換平臺
  • 網(wǎng)站開發(fā) 方案如何注冊網(wǎng)站怎么注冊
  • 網(wǎng)站建設(shè)所需硬件參數(shù)哪個平臺推廣效果最好
  • 企業(yè)級網(wǎng)絡(luò)管理長沙seo網(wǎng)絡(luò)公司
  • 在網(wǎng)上做翻譯的網(wǎng)站市場營銷策劃方案3000字
  • 一級a做爰片免費網(wǎng)站孕交視頻愛戰(zhàn)網(wǎng)關(guān)鍵詞挖掘查詢工具
  • 做網(wǎng)站學(xué)哪個語言最好網(wǎng)絡(luò)推廣人員
  • 只做美食類目產(chǎn)品的網(wǎng)站谷歌play商店
  • 購物網(wǎng)站修改注冊信息模塊的分析唐老鴨微信營銷軟件
  • 北京網(wǎng)站開發(fā)培訓(xùn)網(wǎng)絡(luò)廣告策劃與制作
  • 網(wǎng)站首頁的重要性seo霸屏
  • wordpress 隱藏跳轉(zhuǎn)贛州網(wǎng)站seo
  • 手機自己制作表白網(wǎng)站app產(chǎn)品營銷方案
  • 凡科 預(yù)約網(wǎng)站企業(yè)seo排名哪家好
  • 織夢網(wǎng)站欄目不顯示不出來如何優(yōu)化百度seo排名