Go语言源码分析CAS的实现和Java如出一辙
生活随笔
收集整理的這篇文章主要介紹了
Go语言源码分析CAS的实现和Java如出一辙
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
看了Go的源碼CAS這塊實現(xiàn)和java還是類似的。
關于Java的分析參考:Java使用字節(jié)碼和匯編語言同步分析volatile,synchronized的底層實現(xiàn)
都是使用匯編指令:LOCK+CMPXCHGL
原因很簡單:單核肯定不能發(fā)揮Go的高并發(fā)性能,Go如果要支持多核,必然遇到并發(fā)編程數(shù)據(jù)可見性的問題,底層必然加鎖。
無鎖并不等于沒有鎖,只能說無重量級的鎖而已。
?
Go語言源碼:
Go的CAS是調用CompareAndSwapInt32,
golang中的互斥鎖定義在src/sync/mutex.go:
// Lock locks m.
// If the lock is already in use, the calling goroutine
// blocks until the mutex is available.
func (m *Mutex) Lock() {// Fast path: grab unlocked mutex.if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {if race.Enabled {race.Acquire(unsafe.Pointer(m))}return}
?
無鎖操作CAS:?Compare And Swap 比較并交換。
?源碼在/src/runtime/internal/atomic/asm_amd64.s
可以看到實際上底層還是通過lock來實現(xiàn),關于lock可以參考intel處理器指令。
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.// Note: some of these functions are semantically inlined
// by the compiler (in src/cmd/compile/internal/gc/ssa.go).#include "textflag.h"// bool Cas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// } else
// return 0;
TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0-17MOVQ ptr+0(FP), BXMOVL old+8(FP), AXMOVL new+12(FP), CXLOCKCMPXCHGL CX, 0(BX)SETEQ ret+16(FP)RET// bool runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new)
// Atomically:
// if(*val == *old){
// *val = new;
// return 1;
// } else {
// return 0;
// }
TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25MOVQ ptr+0(FP), BXMOVQ old+8(FP), AXMOVQ new+16(FP), CXLOCKCMPXCHGQ CX, 0(BX)SETEQ ret+24(FP)RETTEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25JMP runtime∕internal∕atomic·Cas64(SB)TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17JMP runtime∕internal∕atomic·Cas(SB)TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-16JMP runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-16JMP runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16JMP runtime∕internal∕atomic·Store64(SB)TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16JMP runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24JMP runtime∕internal∕atomic·Xadd64(SB)// bool Casp1(void **val, void *old, void *new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// } else
// return 0;
TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25MOVQ ptr+0(FP), BXMOVQ old+8(FP), AXMOVQ new+16(FP), CXLOCKCMPXCHGQ CX, 0(BX)SETEQ ret+24(FP)RET// uint32 Xadd(uint32 volatile *val, int32 delta)
// Atomically:
// *val += delta;
// return *val;
TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20MOVQ ptr+0(FP), BXMOVL delta+8(FP), AXMOVL AX, CXLOCKXADDL AX, 0(BX)ADDL CX, AXMOVL AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24MOVQ ptr+0(FP), BXMOVQ delta+8(FP), AXMOVQ AX, CXLOCKXADDQ AX, 0(BX)ADDQ CX, AXMOVQ AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24JMP runtime∕internal∕atomic·Xadd64(SB)TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20MOVQ ptr+0(FP), BXMOVL new+8(FP), AXXCHGL AX, 0(BX)MOVL AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24MOVQ ptr+0(FP), BXMOVQ new+8(FP), AXXCHGQ AX, 0(BX)MOVQ AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24JMP runtime∕internal∕atomic·Xchg64(SB)TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16MOVQ ptr+0(FP), BXMOVQ val+8(FP), AXXCHGQ AX, 0(BX)RETTEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12MOVQ ptr+0(FP), BXMOVL val+8(FP), AXXCHGL AX, 0(BX)RETTEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12JMP runtime∕internal∕atomic·Store(SB)TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16MOVQ ptr+0(FP), BXMOVQ val+8(FP), AXXCHGQ AX, 0(BX)RET// void runtime∕internal∕atomic·Or8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9MOVQ ptr+0(FP), AXMOVB val+8(FP), BXLOCKORB BX, (AX)RET// void runtime∕internal∕atomic·And8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9MOVQ ptr+0(FP), AXMOVB val+8(FP), BXLOCKANDB BX, (AX)RET
這里還有其他處理器的匯編代碼:
?其實這篇文章寫得也還可以:Golang 源代碼解析(一) 鎖機制的研究
總結
以上是生活随笔為你收集整理的Go语言源码分析CAS的实现和Java如出一辙的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 升降机多少钱啊?
- 下一篇: transient HashMap使用目