日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go语言源码分析CAS的实现和Java如出一辙

發(fā)布時間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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如出一辙的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。