C++11原子類型如何使用?答案在這裡,請查收

2020-12-05 軟體技術分享

以前程序運行的時候,都是單線程,順序執行,不需要考慮並發,但是隨著科技的發展,對性能提出了更高的要求,多線程的出現也給單個進程運行的並發提供了基礎。雖然程序支持了並發操作,提高了程序的響應速度,增強了用戶的體驗感,但是同時也給程式設計師的開發工作帶來了難度,需要考慮並發操作時的許多問題,特別是多個線程對共享資源的訪問,如果控制不好,就會造成程序的運行沒法按照預期的效果執行。

所謂的原子操作,就是多線程下「最小並且不可並行化」的操作。而C++11提供了原子類型,這很大程度上簡化程式設計師對並發操作的難度。

本文首先從posix標準的pthread庫提供的互斥鎖開始介紹早期控制多線程並發的操作方式, 接著再重點說明C++11提供的內置原子類型以及模版原子類型的用法,最後再簡單介紹幾個內存模型的含義。

一、poxis互斥鎖

早期實現原子操作,可以藉助posix標準提供的互斥鎖來實現粗力度的互斥。這裡的粗力度是區別於C++11的內存模型來說的。我們來看下poxis互斥鎖的例子。

測試代碼啟動了兩個線程對全局變量g_ll_total進行自增操作,為了保證g_ll_total的原子性,對全局變量g_ll_total修改之前進行加鎖pthread_mutex_lock,修改之後解鎖pthread_mutex_unlock。

運行之後的輸出結果如下,其結果是正確的。從上面的例子看,每次對共享變量的修改,都要進行加鎖解鎖的操作,同時程式設計師還要注意管理互斥鎖,這無疑增加了負擔。

二、內置原子類型

C++11提供了原子類型,分別有內置的原子類型和模版原子類型。我們看下使用內置的原子類型來實現上面相同的功能。

上面的例子中,我們使用了內置原子類型atomic_llong,不需要對共享變量進行加解鎖的操作,但是線程卻能夠對變量g_all_total正確的訪問。

C++11支持的內置原子類型如下表所示

再來看下C++11的內置原子類型基本操作的例子。既可以定義atomic_int類型的變量,然後通過等於進行賦值,也可以在定義atomic_int類型的變量之後通過大括號來直接進行賦值。

三、模版原子類型

C++11除了提供內置的原子類型,更加通用使用方法是類模版的原子類型,通過該類模版,可以自定義需要的原子類型。其使用格式如下,聲明類型為T的原子變量t, 多線程對t的訪問操作就能夠保障正確性。

下面通過例子來說明其使用方法。類模版的定義與內置原子類型的定義基本相似, 但是注意不能使用已經定義的原子類型去初始化新的原子類型。這是因為標準不允許原子類型進行拷貝構造、移動構造等操作。

但是可以使用模版類型變量來初始化其模版參數類型T,比如下面的例子中,我們定義了類型為std::atomic<int>的變量atomic_number1,然後將其賦值給類型為int的變量i_number3。原子類型也提供了load接口來獲取原子類型的值。

類模版原子類型也提供了store的寫操作,來將數據寫入原子類型變量中,store的操作等同於=賦值操作。

C++11支持的操作如下表所示,atomic-integral-type和integral-type指整型的原子類型,class-type是自定義類型。

C++11提供了std::atomic_flag是無鎖的,即線程對其的訪問是不需要加鎖。它支持兩個接口test_and_set和clear, test_and_set是修改atomic_flag為true,然後返回它的舊值。test_and_set的默認參數是std::memory_order_seq_cst,表示順序一致性,這涉及到內存模型的知識,後面將會進行簡單說明。只需要記住的一點是,所有的原子類型都是採用該默認值。

通過std::atomic_flag可以實現線程之間的同步,下面的例子中,首先定義了atomic_flag類型的變量flg_lock,並初始化為ATOMIC_FLAG_INIT。然後再實現兩個線程的執行函數,第一個函數aFunc,通過調用test_and_set來等待獲取atomic_flag的值,如果返回false,那麼往下執行代碼,如果返回true,那麼繼續等待;第二個函數bFunc則執行atomic_flag的接口clear來將其設置為false。最後編寫測試代碼,程序開始的時候調用test_and_set,目的是將flg_lock設置為true, 然後再啟動兩個線程。這樣就實現了線程1等待線程2的通知之後,才繼續往下執行的功能。

四、內存模型含義

C++11的原子類型提供的操作,大部分都使用std::memory_order作為參數,memory_order是一個枚舉類型,其定義如下所示。

memory_order枚舉類型的含義如下

如果不指定參數,那麼原子類型的默認值是memory_order_seq_cst,即順序一致性。但是這會影響程序的並發性能。因此,在實際程序開發過程中,需要根據具體場景來來設置memory_order值。從上表的描述中,可以看出memory_order_acquire是針對當前線程的讀操作,而memory_order_release是針對當前線程的寫操作。特別需要注意的是memory_order_consume是針對當前線程的本原子,但是不影響當前線程的其他原子。

五、總結

至此,已經將原子類型的基本知識及其使用介紹完成。本文主要介紹了內置原子類型和類模版原子類型,另外還簡單介紹了內存模型的知識,關於內存模型只是說明了其概念。深入的介紹,計劃後續通過新的章節來總結。

相關焦點

  • 螞蟻莊園11.18答案請查收
    螞蟻莊園11.18答案請查收     支付寶螞蟻莊園小課堂2020年11月18日答案是什麼呢?2020年11月18日的螞蟻莊園題目是成語「黃髮垂髫」中的「黃髮」指的是?不知道答案的小夥伴一起看看下面今天的螞蟻莊園答案吧!
  • 國戰中哪個武將是五滴血 三國殺2020年7月11日每日一題答案請查收
    國戰中哪個武將是五滴血 三國殺2020年7月11日每日一題答案請查收時間:2020-07-11 09:52   來源:遊俠網   責任編輯:沫朵 川北在線核心提示:原標題:國戰中哪個武將是五滴血 三國殺2020年7月11日每日一題答案請查收 三國殺手遊2020年7月11日微信公眾號每日一題的問題是:國戰中哪個武將是五滴血
  • 這裡有一份徠卡顯微鏡的使用指南,請查收!
    下面請看詳情的性能和使用介紹。一:通過編碼組件存儲和調用信息,想要更換物鏡時,可通過照明強度控制和對比度管理器調用照明強度和光闌的設置。主要得益於編碼物鏡轉盤的存在,攝取的圖像始終得到校準。二:辨識感興趣的結構,25-mm 大視場為您帶來完美的概覽圖像。
  • 最新專家排班表 請您查收!
    最新專家排班表 請您查收! 2020-11-23 16:08 來源:澎湃新聞·澎湃號·政務
  • @共產黨員 你的專用壁紙,請查收!
    @共產黨員 你的專用壁紙,請查收!方能行遠7.老老實實做人踏踏實實幹事清清白白為官8.沒有遠大理想,不是合格的共產黨員9.土能濁河,而不能濁海;風能拔木,而不能拔山10.初心如磐、使命在肩11
  • 螞蟻莊園11.23最新答案...
    螞蟻莊園11.23 答案請查收時間:2020-11-23 00:40   來源:倉鼠手遊   責任編輯:沫朵 川北在線核心提示:原標題:在沒有食物的情況下魚兒嘴巴一張一合是在?螞蟻莊園11.23 答案請查收 支付寶螞蟻莊園小課堂2020年11月23日答案是什麼呢?
  • C++的轉換手段並與explicit關鍵詞配合使用
    ++作者:良知猶存轉載授權以及圍觀:歡迎添加微信公眾號:羽林君隱式轉化c++語言不會直接將兩個不同類型的值相加,二十先根據類型轉化規則設法將運算對象的類型統一後再求值。例如 int value = 3.14 +3;這個程序是可以編譯通過的,只不過編譯器可能會警告改運算損失了精度。
  • 《原神手遊》蒲公英籽怎麼獲得 蒲公英籽分布圖請查收
    《原神手遊》蒲公英籽怎麼獲得 蒲公英籽分布圖請查收時間:2020-11-27 14:47   來源:遊俠網   責任編輯:沫朵 川北在線核心提示:原標題:《原神手遊》蒲公英籽怎麼獲得 蒲公英籽分布圖請查收 原神蒲公英籽怎麼獲得?
  • 【英魂冷知識】離塵使用大百科,請注意查收!
    離塵上線之後在高端局是很多玩家的必出保命裝,關於它的使用技巧請查收! Q 離塵被動可以解除哪些控制技能? 答:離塵被動觸發可以解除所有的控制技能,清除自身的負面狀態。
  • 螞蟻莊園10.14正確答案請查收
    螞蟻莊園10.14正確答案請查收漂亮的金魚是由什麼魚演變而來的?以上是螞蟻莊園小課堂10月14日的問題,答對可以領取小課堂每天一份的180g小雞飼料。接下來就讓我們一起了解一下該問題的答案吧。支付寶螞蟻莊園10月14日小課堂答案一、漂亮的金魚是由什麼魚演變而來的?
  • 請查收哈雷彗星的贈禮
    請查收哈雷彗星的贈禮 2021-01-02 19:24 來源:澎湃新聞·澎湃號·政務
  • 光立方斷崖是一條由什麼顏色方塊組成的小路 龍族幻想11月11日答案...
    最近玩龍族幻想這個遊戲的玩家都在問,遊戲裡面每日一題答案是什麼了?今天的問題是光立方斷崖是一條由什麼顏色方塊組成的小路?大家知道今天每日一題的答案嗎?小編我特意整理了相關的資訊,下面就是蠶豆網小編為大家帶來了龍族幻想11月11日每日一題答案,感興趣的一起來看看吧。
  • 預防一氧化碳中毒,這些知識請您查收!
    預防一氧化碳中毒,這些知識請您查收!今天,就隨警察蜀黍一起學習,在生活中如何避免一氧化碳中毒吧!一、怎樣識別一氧化碳中毒1使用煤炭取暖,室內必需安裝煙囪,煙囪結構要嚴密,排煙排氣良好。空氣溼度大、氣壓低的天氣應格外注意,室內門窗不要封閉過嚴。
  • 【科學防疫】這份防疫小知識請您查收
    【科學防疫】這份防疫小知識請您查收 2021-01-14 17:08 來源:澎湃新聞·澎湃號·政務
  • C++後端開發面試題與知識點匯總(附答案)
    給定三角形ABC和一點P(x,y,z),判斷點P是否在ABC內,給出思路並手寫代碼怎麼判斷一個數是二的倍數,怎麼求一個數中有幾個1,說一下你的思路並手寫代碼請你說一下你理解的c++中的smart pointer四個智能指針:請回答一下數組和指針的區別請你回答一下野指針是什麼?
  • 雪花馬上「到貨」 @黔東南人,請查收……
    雪花馬上「到貨」 @黔東南人,請查收…… 2020-12-02 14:09 來源:澎湃新聞·澎湃號·媒體
  • VR仿真資源|原子吸收分光光度計操作員必備,火焰原子吸收光譜儀操作指南請查收
    原子吸收分光光度計操作員的工作內容主要為樣品中金屬物質的處理和檢測,以重金屬檢測為主,需熟練掌握儀器的使用,能對儀器進行基本的維護。 圖為100唯爾教育火焰原子吸收光譜儀 1.定性分析:判斷樣品中是否含有目標金屬物質或對樣品進行純度判斷。
  • 貫穿C++ 11 與 C++ 17 的 Lambda 到底是個什麼?
    本文將詳解Lambda函數從定義到學習和使用,涉及一些不為人知的事情,如LIFE-立即調用的函數表達式,Lambda的類型。相信你已經起了興趣,那就開始閱讀吧。因此,我們不需要顯式地給它指定一個尾置返回類型,如-> return-type。但在一些複雜的情況下,編譯器無法推斷返回類型,這時候我們就需要給它指定一個返回類型。為什麼我們要使用Lambda函數?C++包含許多有用的通用函數,如std::for_each,它們可以很方便。
  • 【C++】C++獲取系統日期時間
    \n",p->tm_yday); /*從今年1月1日算起至今的天數,範圍為0-365*/}原文:https://blog.csdn.net/u012229282/article/details/79598287  C++時間問題(其中有一些bug)  【轉】2009-10-05 16:20:32|  分類: c++ |  標籤: |
  • 726玉珠峰攀登視頻,請查收!
    726玉珠峰攀登視頻,請查收!