GO原子操作(2)

參數(shù)設(shè)計(jì)
func SwapInt32(addr *int32, new int32) (old int32)
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
func LoadInt32(addr *int32) (val int32)

原子操作函數(shù)的第一個(gè)參數(shù)值對(duì)應(yīng)的都應(yīng)該是那個(gè)被操作的值烦感。比如,atomic.AddInt32函數(shù)的第一個(gè)參數(shù)膛堤,對(duì)應(yīng)的一定是那個(gè)要被增大的整數(shù)手趣。而且參數(shù)的類(lèi)型都是要求是指針類(lèi)型。*int32肥荔。
因?yàn)樵硬僮骱瘮?shù)需要的是被操作值的指針绿渣,而不是這個(gè)值本身;被傳入函數(shù)的參數(shù)值都會(huì)被復(fù)制燕耿,像這種基本類(lèi)型的值一旦被傳入函數(shù)中符,就已經(jīng)與函數(shù)外的那個(gè)值毫無(wú)關(guān)系了所以,傳入值本身沒(méi)有任何意義誉帅。unsafe.Pointer類(lèi)型雖然是指針類(lèi)型淀散,但是那些原子操作函數(shù)要操作的是這個(gè)指針值谭期,而不是它指向的那個(gè)值,所以需要的仍然是指向這個(gè)指針值的指針吧凉。
只要原子操作函數(shù)拿到了被操作值的指針隧出,就可以定位到存儲(chǔ)該值的內(nèi)存地址。只有這樣阀捅,它們才能夠通過(guò)底層的指令胀瞪,準(zhǔn)確地操作這個(gè)內(nèi)存地址上的數(shù)據(jù)。

原子減法

atomic只提供了add相關(guān)的方法饲鄙,并沒(méi)有提供減法凄诞。但是atomic.AddInt32函數(shù)的第二個(gè)參數(shù)代表差量,它的類(lèi)型是int32忍级,是有符號(hào)的帆谍。如果我們想做原子減法,那么把這個(gè)差量設(shè)置為負(fù)整數(shù)就可以了轴咱。
無(wú)符號(hào)類(lèi)型如:uint32可以下方法轉(zhuǎn)化:
方法一:

uint32(int32(-N))

方法二:

^uint32(-N-1))

其中的N代表由負(fù)整數(shù)表示的差量汛蝙。

交換與比較并交換

交換(swap)把新值賦給變量,并返回變量的舊值
比較并交換(compare and swap朴肺,簡(jiǎn)稱CAS)是有條件的交換操作窖剑,只有在條件滿足的情況下才會(huì)進(jìn)行值的交換。在進(jìn)行CAS操作的時(shí)候戈稿,函數(shù)會(huì)先判斷被操作變量的當(dāng)前值西土,是否與我們預(yù)期的舊值相等。如果相等鞍盗,它就把新值賦給該變量需了,并返回true以表明交換操作已進(jìn)行;否則就忽略交換操作般甲,并返回false肋乍。

CAS操作并不是單一的操作,而是一種操作組合欣除。應(yīng)用要更廣泛一些住拭,如自旋鎖

for {
 if atomic.CompareAndSwapInt32(&num2, 10, 0) {
  fmt.Println("The second number has gone to zero.")
  break
 }
 time.Sleep(time.Millisecond * 500)
}

網(wǎng)上也有一些人用CAS做無(wú)鎖編程所謂無(wú)鎖編程只是將多條指令合并成了一條指令形成一個(gè)邏輯完備的最小單元挪略,通過(guò)兼容CPU指令執(zhí)行邏輯形成的一種多線程編程模型

載入與存儲(chǔ)

載入Load 原子性的讀取一個(gè)變量的值历帚,確保在不會(huì)讀到被修改到一半的值
存儲(chǔ)Store原子地存儲(chǔ)某個(gè)值的過(guò)程中,任何CPU都不會(huì)進(jìn)行針對(duì)同一個(gè)值的讀或?qū)懖僮?/p>

思考

問(wèn)題1:為什么不設(shè)計(jì)比較(compare)如果設(shè)計(jì)了比較(compare) 杠娱,在一段代碼中挽牢, 我們先 比較(compare) 得出結(jié)果后再 交換(swap)。將CAS操作分成兩步走還是原子是否安全摊求?

答案肯定是不安全禽拔,compare 是原子的 swap 是原子,單不代表這兩的組合是原子的。不設(shè)計(jì)compare原因應(yīng)該是意義不大睹栖,CAS操作本身也可以實(shí)現(xiàn)compare硫惕,而且compare后往往還需跟其他的操作,swap通常是最嘗被使用的野来。

問(wèn)題 2:假設(shè)我已經(jīng)保證了對(duì)一個(gè)變量的寫(xiě)操作都是原子操作恼除,比如:加或減、存儲(chǔ)曼氛、交換等等豁辉,那我對(duì)它進(jìn)行讀操作的時(shí)候,還有必要使用原子操作嗎舀患?

答案是很有必要其中的道理你可以對(duì)照一下讀寫(xiě)鎖徽级。為什么在讀寫(xiě)鎖保護(hù)下的寫(xiě)操作和讀操作之間是互斥的?這是為了防止讀操作讀到?jīng)]有被修改完的值聊浅,對(duì)嗎餐抢?
如果寫(xiě)操作還沒(méi)有進(jìn)行完,讀操作就來(lái)讀了低匙,那么就只能讀到僅修改了一部分的值弹澎。這顯然破壞了值的完整性,讀出來(lái)的值也是完全錯(cuò)誤的努咐。所以苦蒿,一旦你決定了要對(duì)一個(gè)共享資源進(jìn)行保護(hù),那就要做到完全的保護(hù)渗稍。不完全的保護(hù)基本上與不保護(hù)沒(méi)有什么區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佩迟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子竿屹,更是在濱河造成了極大的恐慌报强,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拱燃,死亡現(xiàn)場(chǎng)離奇詭異秉溉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碗誉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)召嘶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人哮缺,你說(shuō)我怎么就攤上這事弄跌。” “怎么了尝苇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵铛只,是天一觀的道長(zhǎng)埠胖。 經(jīng)常有香客問(wèn)我,道長(zhǎng)淳玩,這世上最難降的妖魔是什么直撤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蜕着,結(jié)果婚禮上谊惭,老公的妹妹穿的比我還像新娘。我一直安慰自己侮东,他們只是感情好圈盔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著悄雅,像睡著了一般驱敲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宽闲,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天众眨,我揣著相機(jī)與錄音,去河邊找鬼容诬。 笑死娩梨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的览徒。 我是一名探鬼主播狈定,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼习蓬!你這毒婦竟也來(lái)了纽什?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躲叼,失蹤者是張志新(化名)和其女友劉穎芦缰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體枫慷,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡让蕾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了或听。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片探孝。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖神帅,靈堂內(nèi)的尸體忽然破棺而出再姑,到底是詐尸還是另有隱情,我是刑警寧澤找御,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布元镀,位于F島的核電站,受9級(jí)特大地震影響霎桅,放射性物質(zhì)發(fā)生泄漏栖疑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一滔驶、第九天 我趴在偏房一處隱蔽的房頂上張望遇革。 院中可真熱鬧,春花似錦揭糕、人聲如沸萝快。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)揪漩。三九已至,卻和暖如春吏口,著一層夾襖步出監(jiān)牢的瞬間奄容,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工产徊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昂勒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓舟铜,卻偏偏與公主長(zhǎng)得像戈盈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谆刨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容