您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關大數據中如何淺析多線程數據訪問一致性問題及解決方法,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
服務器和筆記本電腦都使用多核CPU,出于性能考慮,每個CPU采用了獨享的Cache機制(通常有兩級獨享cache和一級共享cache),由此帶來并發訪問內存中的同一數據,在不同CPU上的可見性或一致性問題。CPU采用Cache機制帶來多線程訪問共享數據的一致性或數據可見性問題,是從事多線程編程的工程師們繞不過去的坎兒。
知道了問題所在,解決并發訪問下數據一致性問題的方法有多種。最常用的就是加鎖方式,比如C/C++下直接使用線程鎖實現訪問互斥,同時也能保證數據修改后的可見性。對于計數器場景,還可以采用性能更高的原子操作(其性能大約是線程鎖的6倍),例如gcc內置的 __sync_add_and_fetch / __sync_fetch_and_add 或 __sync_sub_and_fetch / __sync_fetch_and_sub 等函數。另外可以利用CAS(Compare And Swap)原子操作實現無鎖編程,例如gcc內置的__sync_bool_compare_and_swap 和 __sync_val_compare_and_swap。比如我們可以利用CAS實現無鎖隊列。
對于一個生產者和一個消費者的線程模型,使用ring buffer這樣的數據結構,因不存在訪問沖突的問題,可以采用無鎖化編程。比如Linux內核處理ring buffer,結合使用內存屏障,可以在無鎖的情況下保證數據可見性。內存屏障這塊比較深奧,我在這方面沒有研究和實踐,在這里拋個磚就好。
針對一個線程修改數據,多個線程讀取的場景,一種更為極端的無鎖編程方式:不但徹底無鎖(不需要CAS),而且還不使用內存屏障來保證數據可見性。這種做法顯然違背了并發訪問的數據一致性,但對于可接受數據最終一致的場景,這種做法是完全可行的。這是為什么呢?一個線程修改數據后,因CPU cache機制,其他線程將延遲感知到修改后的數據。根據筆者經驗,這個延遲通常在1ms以內。因為沒有采用加鎖或內存屏障等機制,數據在多線程下的可見性存在不確定性。對于大多數數據結構(如平衡二叉樹、紅黑樹、skiplist、hashtable等)的數據修改通常會分為多個步驟完成,在此友情提醒大家,采用這種做法的一個前提條件是,當讀取線程讀到部分更新后的數據時,不會導致程序邏輯錯亂甚至出現崩潰等異常情況發生。平衡二叉樹這樣的數據結構很難采用這種編程模型(因保持平衡涉及旋轉操作,需要一把大鎖保護),而精心實現的skiplist和hashtable是可以做到的。
上述就是小編為大家分享的大數據中如何淺析多線程數據訪問一致性問題及解決方法了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。