国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

深入理解無鎖編程

開發(fā)
無鎖編程是一個挑戰(zhàn),不僅因為任務(wù)本身的復(fù)雜性,還因為從一開始就很難深入了解這個主題,因為該主題和底層技術(shù)(編譯器,CPU,內(nèi)存)息息相關(guān),需要深厚底層功底。

[[412990]]

本文轉(zhuǎn)載自微信公眾號「極客重生」,作者極客重生。轉(zhuǎn)載本文請聯(lián)系極客重生公眾號。

hi,大伙好,今天介紹一下無鎖編程基礎(chǔ)知識,希望大家可以了解無鎖編程基本原理。

無鎖編程是一個挑戰(zhàn),不僅因為任務(wù)本身的復(fù)雜性,還因為從一開始就很難深入了解這個主題,因為該主題和底層技術(shù)(編譯器,CPU,內(nèi)存)息息相關(guān),需要深厚底層功底。

我學(xué)習(xí)無鎖編程是Bruce Dawson 出色而全面的白皮書Lockless Programming Considerations(無鎖編程的思考)。和許多技術(shù)一樣,需要將理論付諸實踐,在平臺上開發(fā)和調(diào)試無鎖代碼。

在這篇文章中,我想重新介紹無鎖編程,首先是定義它,然后將大部分信息提煉為幾個關(guān)鍵概念。我將使用流程圖展示這些概念如何相互關(guān)聯(lián),然后我們將深入研究細(xì)節(jié)。至少,任何從事無鎖編程的程序員都應(yīng)該已經(jīng)了解如何使用互斥鎖和其他高級同步對象(如信號量和事件)編寫正確的多線程代碼。

它是什么?

人們通常將無鎖編程描述為沒有互斥鎖的編程,互斥鎖也稱為鎖。這是真的,但這只是故事的一部分?;趯W(xué)術(shù)文獻(xiàn)的普遍接受的定義更廣泛一些。從本質(zhì)上講,無鎖是一種用于描述某些代碼的屬性,而無需過多說明該代碼的實際編寫方式。

基本上,如果您的程序的某些部分滿足以下條件,那么該部分可以理所當(dāng)然地被認(rèn)為是無鎖的。相反,如果代碼的給定部分不滿足這些條件,則該部分不是無鎖的。

從這個意義上說,無鎖中的鎖并不直接指互斥鎖,而是指以某種方式“鎖定”整個應(yīng)用程序的可能性,無論是死鎖、活鎖——甚至是由于由你最大的敵人。最后一點聽起來很有趣,但這是關(guān)鍵。共享互斥鎖被簡單地排除在外,因為一旦一個線程獲得互斥鎖,您最大的敵人就再也不會調(diào)度該線程了。當(dāng)然,真正的操作系統(tǒng)不是這樣工作的——我們只是定義術(shù)語。

這是一個不包含互斥鎖但仍然不是無鎖的操作的簡單示例。最初,X = 0。作為讀者的練習(xí),考慮如何以一種方式調(diào)度兩個線程,使得兩個線程都不退出循環(huán)。

  1. while(X == 0 ) {  
  2.     X = 1 - X;  

沒有人期望大型應(yīng)用程序是完全無鎖的。通常,我們從整個代碼庫中識別出一組特定的無鎖操作。例如,在一個無鎖隊列中,有可能是無鎖的操作,比如極少數(shù)的push,pop也許isEmpty等。

Herlihy & Shavit 是The Art of Multiprocessor Programming(多處理器編程的藝術(shù)) 的作者,傾向于將此類操作表示為類方法,并提供以下無鎖的簡潔定義:

“在無限執(zhí)行中,某些方法調(diào)用會無限頻繁地結(jié)束”

換句話說,只要程序能夠繼續(xù)調(diào)用那些無鎖操作,無論發(fā)生什么,完成的調(diào)用次數(shù)都會不斷增加。在這些操作期間,系統(tǒng)在算法上不可能鎖定。

無鎖編程的一個重要結(jié)論是,如果您掛起單個線程,它永遠(yuǎn)不會阻止其他線程作為一個組通過它們自己的無鎖操作取得進(jìn)展。這暗示了在編寫中斷處理程序和實時系統(tǒng)時無鎖編程的價值,其中某些任務(wù)必須在一定的時間限制內(nèi)完成,無論程序的其余部分處于什么狀態(tài)。

最后一個說明:某些操作被設(shè)計為阻塞的并不意味是這就不是Lock-Free的。例如,當(dāng)隊列為空時,隊列的彈出操作可能會故意阻塞。其余的代碼路徑仍然可以被認(rèn)為是無鎖的。

無鎖編程技術(shù)

事實證明,當(dāng)您嘗試滿足無鎖編程的非阻塞條件時,會出現(xiàn)一整套技術(shù):原子操作、內(nèi)存屏障、避免 ABA 問題,僅舉幾例。這就是事情很快變得邪惡的地方。

那么這些技術(shù)如何相互關(guān)聯(lián)呢?為了說明,我整理了以下流程圖。下面我將逐一詳述。

原子讀-修改-寫操作

原子操作是以一種看起來不可分割的方式操作內(nèi)存的操作:沒有線程可以觀察到半完成的操作。在現(xiàn)代處理器上,許多操作已經(jīng)是原子的。例如,簡單類型的對齊讀取和寫入通常是原子的。

讀-修改-寫(RMW) 操作更進(jìn)一步,允許您以原子方式執(zhí)行更復(fù)雜的事務(wù)。當(dāng)無鎖算法必須支持多個寫入器時,它們特別有用,因為當(dāng)多個線程在同一地址上嘗試 RMW 時,它們將有效地排成一行并一次執(zhí)行這些操作。我已經(jīng)在這篇博客中談到了 RMW 操作,例如實現(xiàn)輕量級互斥鎖、遞歸互斥鎖和輕量級日志系統(tǒng)時。

RMW 操作的示例包括_InterlockedIncrementWin32、OSAtomicAdd32iOS 和std::atomic::fetch_addC++11。請注意,C++11 原子標(biāo)準(zhǔn)并不能保證實現(xiàn)在每個平臺上都是無鎖的,因此最好了解您的平臺和工具鏈的功能。你可以使用std::atomic<>::is_lock_free確認(rèn)一下。

不同的 CPU 系列以不同的方式支持 RMW。諸如 PowerPC 和 ARM 之類的處理器公開了load-link/store-conditional)條件指令,這有效地允許您在低級別實現(xiàn)自己的 RMW 原語,盡管這并不常見。常見的 RMW 操作通常就足夠了。

如流程圖所示,即使在單處理器系統(tǒng)上,原子 RMW 也是無鎖編程的必要部分。如果沒有原子性,線程可能會在事務(wù)中途中斷,從而可能導(dǎo)致狀態(tài)不一致。

Compare-And-Swap Loops

也許最常討論的 RMW 操作是compare-and-swap(CAS)。在 Win32 上,CAS 是通過一系列內(nèi)在函數(shù)提供的,例如_InterlockedCompareExchange. 通常使用 CAS Loops 來完成對事務(wù)的原子處理:

  1. void LockFreeQueue::push(Node* newHead) 
  2.     for (;;) 
  3.     { 
  4.         // Copy a shared variable (m_Head) to a local
  5.         Node* oldHead = m_Head; 
  6.  
  7.         // Do some speculative worknot yet visible to other threads. 
  8.         newHead->next = oldHead; 
  9.  
  10.         // Next, attempt to publish our changes to the shared variable. 
  11.         // If the shared variable hasn't changed, the CAS succeeds and we return
  12.         // Otherwise, repeat. 
  13.         if (_InterlockedCompareExchange(&m_Head, newHead, oldHead) == oldHead) 
  14.             return
  15.     } 

這樣的循環(huán)仍然符合無鎖的條件,因為如果一個線程的測試失敗,則意味著它必須在另一個線程上成功——盡管某些架構(gòu)提供了CAS的較弱變體,而這不一定是真的。每當(dāng)實現(xiàn) CAS 循環(huán)時,必須特別注意避免ABA 問題。

順序一致性

順序一致性是指所有線程都同意內(nèi)存操作發(fā)生的順序,并且該順序與程序源代碼中的操作順序一致。

實現(xiàn)順序一致性的一種簡單(但顯然不切實際)的方法是禁用編譯器優(yōu)化并強(qiáng)制所有線程在單個處理器上運(yùn)行。處理器永遠(yuǎn)不會看到它自己的內(nèi)存效果出問題,即使線程在任意時間被搶占和調(diào)度。

一些編程語言即使對于在多處理器環(huán)境中運(yùn)行的優(yōu)化代碼也提供順序一致性。在 C++11 中,您可以將所有共享變量聲明為具有默認(rèn)內(nèi)存排序約束的 C++11 原子類型。在 Java 中,您可以將所有共享變量標(biāo)記為volatile. 這是我上一篇文章中的示例,以 C++11 風(fēng)格重寫:

  1. std::atomic< int > X( 0 ), Y( 0 ); 
  2. int r1, r2; 
  3.  
  4. void thread1() 
  5. {  
  6.     X.store( 1 );  
  7.     r1 = Y.load(); 
  8.  
  9. void thread2() 
  10. {  
  11.     Y.store( 1 );  
  12.     r2 = X.load();  

因為 C++11 原子類型保證順序一致性,結(jié)果 r1 = r2 = 0 是不可能的。為了實現(xiàn)這一點,編譯器會在幕后輸出額外的指令——通常是內(nèi)存柵欄和/或 RMW 操作。與程序員直接處理內(nèi)存排序的指令相比,這些附加指令可能會降低實現(xiàn)的效率。

內(nèi)存排序

正如流程圖所暗示的那樣,任何時候您對多核(或任何對稱多處理器)進(jìn)行無鎖編程,并且您的環(huán)境不保證順序一致性,您必須考慮如何防止內(nèi)存重新排序。

在當(dāng)今的體系結(jié)構(gòu)中,強(qiáng)制執(zhí)行正確內(nèi)存排序的工具通常分為三類,它們可以防止編譯器重新排序和處理器重新排序:

  • 輕量級同步或柵欄指令;
  • 一個完整的內(nèi)存柵欄指令;
  • 提供獲取或釋放語義的內(nèi)存操作。

獲取語義防止在程序順序中跟隨它的操作的內(nèi)存重新排序,并且釋放語義防止在它之前的操作的內(nèi)存重新排序。這些語義特別適用于存在生產(chǎn)者/消費(fèi)者關(guān)系的情況,即一個線程發(fā)布一些信息而另一個線程讀取它。

不同的處理器有不同的內(nèi)存模型

不同的 CPU 系列在內(nèi)存重新排序方面有不同的習(xí)慣。這些規(guī)則由每個 CPU 供應(yīng)商記錄,并由硬件嚴(yán)格遵守。例如,PowerPC 和 ARM 處理器可以更改相對于指令本身的內(nèi)存存儲順序,但通常情況下,Intel 和 AMD 的 x86/64 系列處理器不會。我們說前者的處理器具有更寬松的內(nèi)存模型。

人們很容易抽象出這些特定于平臺的細(xì)節(jié),尤其是 C++11 為我們提供了一種編寫可移植無鎖代碼的標(biāo)準(zhǔn)方法。但是目前,我認(rèn)為大多數(shù)無鎖程序員至少對平臺差異有一些了解。如果要記住一個關(guān)鍵區(qū)別,那就是在 x86/64 指令級別,每次從內(nèi)存加載都帶有獲取語義,并且每次存儲到內(nèi)存都提供釋放語義——至少對于非 SSE 指令和非寫組合內(nèi)存. 因此,過去常常編寫能在x86/64 上運(yùn)行成功但在其他處理器上失敗的無鎖代碼。

如果你對處理器需要內(nèi)存排序的硬件細(xì)節(jié)感興趣,我推薦附錄的并行編程困難嗎? 請記住在任何情況下,由于編譯器指令重排序也會導(dǎo)致內(nèi)存重新排序。

在這篇文章中,我沒有過多地談?wù)摕o鎖編程的實際方面,例如:我們什么時候做?我們真正需要多少?我也沒有提到驗證無鎖算法的重要性。盡管如此,我希望對于一些讀者來說,這篇介紹已經(jīng)提供了對無鎖概念的基本熟悉,因此您可以繼續(xù)深入閱讀其他文章而不會感到太困惑。

參考資料 & 擴(kuò)展閱讀

 

  • Anthony Williams’ blog and his book, C++ Concurrency in Action
  • Dmitriy V’jukov’s website and various forum discussions
  • Bartosz Milewski’s blog
  • Charles Bloom’s Low-Level Threading series on his blog
  • Doug Lea’s JSR-133 Cookbook
  • Howells and McKenney’s memory-barriers.txt document
  • Hans Boehm’s collection of links about the C++11 memory model
  • Herb Sutter’s Effective Concurrency series
  • http://preshing.com/20120612/an-introduction-to-lock-free-programming/

 

責(zé)任編輯:武曉燕 來源: 極客重生
相關(guān)推薦

2019-06-25 10:32:19

UDP編程通信

2023-10-13 13:30:00

MySQL鎖機(jī)制

2022-07-04 08:01:01

鎖優(yōu)化Java虛擬機(jī)

2020-12-11 07:32:45

編程ThreadLocalJava

2020-11-13 08:42:24

Synchronize

2022-10-12 07:53:46

并發(fā)編程同步工具

2018-03-22 18:30:22

數(shù)據(jù)庫MySQL并發(fā)控制

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2020-07-21 08:26:08

SpringSecurity過濾器

2010-06-01 15:25:27

JavaCLASSPATH

2019-03-18 15:36:32

無服務(wù)器FaasServerless

2024-12-31 09:00:12

Java線程狀態(tài)

2023-10-31 10:51:56

MySQLMVCC并發(fā)性

2019-02-12 14:24:14

緩存高并發(fā)網(wǎng)絡(luò)

2009-09-25 09:14:35

Hibernate日志

2021-02-17 11:25:33

前端JavaScriptthis

2023-10-19 11:12:15

Netty代碼

2013-09-22 14:57:19

AtWood

2025-06-05 05:51:33

2020-09-23 10:00:26

Redis數(shù)據(jù)庫命令
點贊
收藏

51CTO技術(shù)棧公眾號

久久久久久av无码免费网站下载| 牛夜精品久久久久久久| 91久久精品一区二区别| 日本久久久久久久久| 精品少妇v888av| www.日韩视频| 中文字幕亚洲无线码在线一区| 精品一区二区三区三区| 日韩一区二区电影在线| 欧美日韩在线影院| 五月开心婷婷久久| 亚洲高清三级视频| 一区二区日韩av| 夜色激情一区二区| 一区二区三区91| 亚洲国产日日夜夜| 午夜天堂影视香蕉久久| 五月激情六月综合| 色综合久久天天综合网| 色综合婷婷久久| 日韩欧美aaa| 欧美性猛交xxx| 欧美性猛交xxxx富婆弯腰| 欧美日韩在线看| 欧美性色视频在线| 欧美在线短视频| 欧美另类高清zo欧美| 91精品国产全国免费观看| 91精品国产色综合久久不卡蜜臀| 欧美高清www午色夜在线视频| 91精品国产色综合久久不卡蜜臀| 日韩精品一区二区三区三区免费| 亚洲国产精品电影在线观看| 亚洲欧美日韩高清| 久久视频这里只有精品| 97久久精品人搡人人玩| 欧美在线观看一区二区三区| 国产999精品| 91在线网站视频| 成人免费看片网站| 久久久久久久久久久久久久一区| 欧美亚洲丝袜| 精品国产三级a∨在线| www.浪潮av.com| 啊啊啊好爽视频| 激情五月色综合亚洲小说| 国产在线传媒| seseavlu视频在线| 久久久123| 色999久久久精品人人澡69 | 男人天堂综合| 黄色av网站在线播放| 自拍网站在线观看| 亚洲一区二区三区四区电影| 成人在线免费小视频| 在线免费高清一区二区三区| 蜜桃av噜噜一区| 久久综合av免费| 亚洲永久免费视频| 欧美久久久久久久久久| 国产视频在线一区二区| 欧美黄色www| 91丝袜美腿美女视频网站| 欧洲一区二区在线| 欧美男女爱爱视频| 成年免费网站| 毛片网站在线免费观看| 999国产精品亚洲77777| 欧洲专线二区三区| 亚洲欧美高清| www.日韩av| 亚洲午夜久久久久中文字幕久| 欧美日韩成人综合| 自拍偷拍亚洲区| 国产精品成人久久久久| 久久一区二区精品| 奇米精品一区二区三区| 在线观看黄色小视频| 免费网站在线观看人| 欧美视频二区欧美影视| 午夜激情一区| 处破女av一区二区| 亚洲在线观看免费| 亚洲激情视频网站| 2020欧美日韩在线视频| 久久国产精品 国产精品| 91视频 -- 69xx| 天堂а在线中文在线无限看推荐| 欧美办公室脚交xxxx| 杨幂一区二区三区免费看视频| 噜噜噜在线观看免费视频日韩| 久久久噜噜噜久久人人看| 色老头久久综合| 色天天综合狠狠色| 91热精品视频| 丁香六月激情网| 亚洲无限乱码一二三四麻| 青草av在线| 蜜臀91精品国产高清在线观看| 视频一区视频二区在线观看| 国产精品女主播在线观看| 制服丝袜一区二区三区| 久久99精品久久久久久噜噜| 精品国产一区二区三区四区vr| 日本一区二区黄色| 日本最新在线视频| 国产精品久久久久av蜜臀| 老鸭窝毛片一区二区三区| 国产精品美女久久久久aⅴ国产馆| 欧美一区二区福利在线| 欧洲精品久久久| 日韩精品一区二区三区电影| 日韩午夜影院| 国产精区一区二区| 亚洲免费中文| 一区二区三区在线视频播放| 一本一本久久a久久精品牛牛影视 一本色道久久综合亚洲精品小说 一本色道久久综合狠狠躁篇怎么玩 | 日韩小视频在线观看| 亚洲一区亚洲二区| 少妇性饥渴无码a区免费| 欧美私人网站| 欧美人妖视频| 国产一区二区剧情av在线| 色婷婷综合久久久久中文一区二区 | 成人网在线免费观看| 亚洲高清不卡一区| www.999av| 波多野结衣精品| 久久亚洲国产| 成人avav影音| 91精品欧美综合在线观看最新| 热久久99这里有精品| 国产亚洲精品久久久久久久| 成人在线视频成人| 久久久久观看| 国产东北露脸精品视频| 欧美日韩一级二级三级| 欧美亚洲成人免费| 国产不卡一区二区视频| 成人在线直播| 国产精品久久久久久麻豆一区软件 | 亚洲精品美女在线| 亚洲自拍偷拍视频| av在线无限看| 成人欧美大片| 99精品热视频只有精品10| 亚洲六月丁香色婷婷综合久久| 在线视频免费一区二区| 欧美在线播放一区| 黄色在线网站| 欧美理论在线播放| 中文字幕av一区二区三区| 精品在线小视频| 久久久亚洲综合网站| 在线观看av每日更新免费| 超碰97久久| www.视频一区| 日韩精品www| 日本一区二区三区免费看| 久久久久久青草| 成人看的羞羞网站| 亚洲欧洲另类国产综合| 久久中文字幕在线视频| 国产又粗又长又爽视频| 欧美日韩经典丝袜| 亚洲黄色影片| 色婷婷香蕉在线一区二区| 国产91精品在线播放| 国产三区在线视频| 国产91在线播放精品| 极品美女销魂一区二区三区免费| 91精品国产全国免费观看 | 亚洲一区欧美二区| 色视频欧美一区二区三区| 国产成人亚洲综合91| 三上悠亚在线一区二区| 国产亚洲精aa在线看| 国产激情精品久久久第一区二区 | 99久热在线精品视频| 日本小视频在线免费观看| 亚洲巨乳在线| 欧美怡红院视频| 91在线观看免费观看| 成r视频免费观看在线播放| 美女一区二区在线观看| 国产日韩欧美精品在线| 久久亚洲私人国产精品va| 人人妻人人澡人人爽欧美一区双| 国产精品电影| 精品中文av资源站在线观看| 亚洲国产精品va| 日本三日本三级少妇三级66| 国产伦理精品| 国产乱一区二区| 国产性猛交xxxx免费看久久| 欧美一区二区视频在线播放| 激情小说亚洲| 久久美女艺术照精彩视频福利播放| 欧美精品一区三区| 亚洲免费一级视频|