「阿Q趕快回去吧,隔壁二號車間的虎子說咱們改了他們的數據,上門來鬧事了」程序員
因爲老K的忽然出現,我不得不提早結束與小黑的交流,趕回了CPU一號車間。編程
見到我回來,虎子馬上朝我嚷嚷:「大家是怎麼回事?才幾納秒的時間,就把數據給我改了,你說這事怎麼辦吧!」緩存
我聽着迷迷糊糊的,連連說到:「虎子你先別急,我剛回來,到底出什麼事兒了,先讓我瞭解清楚好很差?」編程語言
接下來,老K把事情的通過告訴了我。原來,咱們兩個CPU車間各自負責的線程都在執行一個i++
的操做,咱們都把i
的值放到了本身的緩存中,完了以後都沒有通知對方,加了兩次但結果卻只有一次,出現了數據不一致問題
。源碼分析
瞭解清楚事情的原委以後,我向虎子說道:「你們都執行同樣的代碼,這事兒也不能怪咱們啊」線程
虎子一聽急了,「怎麼不怪大家了,咱們比大家先一步找內存拿走了i,那大家得等咱們加完以後再用啊,不信你能夠打電話問內存那傢伙,看看是否是咱們二號車間先來的」3d
「好好好,你先冷靜一下,你看咱們又不知道大家先去拿了,這不情有可原嗎,再說如今事情已經出了,咱們應該一塊兒坐下來想個辦法避免之後再次出現這種問題,你說是否是?」code
虎子嘆了口氣問道:「那你說說你有什麼辦法?」對象
我繼續說道:「你看啊,像我們在執行i++
這種操做的時候就不該該被幹擾」blog
「不被幹擾?」
「對,好比虎子大家二號車間在訪問i的時候,咱們一號車間就不能訪問,須要等着,等大家訪問完成咱們再來,很是簡單的辦法卻頗有用」
虎子聽完一愣,「這不就是加鎖嗎?你是想怪程序員作i++前沒有加鎖?」
「的確是加鎖,不過這種簡單操做還要程序員來加鎖那也太麻煩了,我們CPU內部處理好就好了」
「內部處理,你打算怎麼實現?」,虎子問到。
「這,,讓我想一想···」,虎子問到了具體實現,我倒還沒想到這一步。
這時,一旁的老K站了出來:「我卻是有個辦法,能夠找總線主任啊,他是負責協調各個車間使用系統總線訪問內存的總指揮,讓他在中間協調一下應該不難」
老K一語點醒夢中人,接着咱們就去找了總線主任,後來咱們商量出了一套解決方案:咱們定義了一個叫原子操做
的東西,表示這是一個不可切分的動做,誰要執行原子操做,總線主任就在系統總線上加上一個LOCK#
信號,其餘車間的想去訪問內存就得等着,直到原子操做指令執行完畢。
咱們把這套方案上報了領導,很快就批下來了,後面咱們8個車間都按照這套方案來工做,之後程序員們把i++這樣的動做換成原子操做後,問題就能迎刃而解。
不過施行了一段時間以後,各個車間卻開始大倒苦水:就由於某個車間要執行一個原子操做,就讓總線主任把系統總線鎖住,其餘車間的人都無法訪問內存,都幹不了活了,嚴重影響工做效率。
抱怨歸抱怨,在沒有更好的替代方案出現以前,日子還得過下去。
不過,沒過多久,數據不一致問題又一次出現了。
這一次,倒不是加法的問題,咱們兩車間仍是由於各自緩存的緣由,前後修改了變量的值,對方沒有即時知道,誤用了錯誤的值,以至釀成大錯。
「阿Q,上次那辦法好是好,可解決不了這一次的問題啊」,虎子再次找上門來。
「你來的正好,我正想去找你說這事呢」
「哦,是嗎,難不成你想到破解之道了?」
「只是一些初步的想法,問題的核心在於如今我們各個車間各自爲政,都有本身的私有緩存,各自修改數據後向內存更新時也不互相打招呼,缺乏一個聯絡機制」
虎子點了點頭,「確實,因此我們須要創建一個聯絡機制,來對各個車間的緩存內容進行統一管理是嗎?」
「對!這事兒咱倆說了可不算,我建議召集8個核心車間的表明,統一開一個會議,詳細討論下這個問題。哦,對了,把總線主任也叫上,他經驗豐富說不定能提供一些思路」
很快,我們CPU的8個核心車間就爲此問題召開了會議,而且取得了很是重要的成果。
咱們牽了一條新的專線,把8個核心車間鏈接起來,用於各個車間之間進行信息溝通,不一樣於CPU外部的總線系統,你們把這個叫片內總線
。
新的線路鋪設好了,之後你們就能夠經過這條線路即時溝通,爲了解決以前出現的問題,你們還制定了一套規則,叫作緩存一致性協議
。
規則裏面規定了全部車間的緩存單元——緩存行
有四種狀態:
緩存行已經被修改了,與內存的值不同。若是別的CPU內核要讀內存這塊數據,要趕在這以前把該緩存行回寫到主存,把狀態變爲共享(S).
緩存行只在當前CPU核心緩存中,並且和內存中數據同樣。當別的CPU核心讀取它時,狀態變爲共享;若是當前CPU核心修改了它,就要變爲已修改狀態。
緩存行存在於多個CPU核心的緩存中,並且和內存中的內容一致。
緩存行是無效的
四種狀態之間的轉換是這樣的:
按照這套規則,你們不能再像之前那樣隨意了,各車間對自家緩存進行讀寫時,都要相互通一下氣,避免使用過期的數據。
除此以外,還規定若是一塊內存區域被多個車間都緩存,就再也不容許多個車間同時去修改緩存了。
會議還有另一個收穫,之前被各車間詬病的每次原子操做都要鎖定總線,致使你們須要訪問內存的都只能乾等着的問題也獲得瞭解決。之後總線主任再也不須要鎖定總線了,經過此次的緩存一致性協議就能夠辦到。
自此之後,數據不一致的問題總算是根治了,我們8個車間又能夠愉快的工做了。