Go语言源码分析CAS的实现和Java如出一辙
看了Go的源码CAS这块实现和java还是类似的。
关于Java的分析参考:Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现
都是使用汇编指令:LOCK+CMPXCHGL
原因很简单:单核肯定不能发挥Go的高并发性能,Go如果要支持多核,必然遇到并发编程数据可见性的问题,底层必然加锁。
无锁并不等于没有锁,只能说无重量级的锁而已。
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来实现,关于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如出一辙相关推荐
- Android 切换系统语言源码分析
以前了解Android的多语言实现很简单,可以在不同的语言环境下使用不同的资源,就做好相应的语言适配就好,但是一直没有实际使用过. 最近公司的项目要用到多国语言切换,并且还是和手机上系统设置里面的语言 ...
- vitamio官方demo源码分析(1)——MediaPlayerDemo_Video.java分析
最近在做一个视频监控项目的android客户端,要求用rtsp协议完成视频流的传输,但苦于找到不合适的库.之前考虑过用live555或ffmpeg,但涉及到jni调用,加之不熟悉函数调用顺序,开发难度 ...
- Jedis 1.0.0 版 源码分析系列3:JedisPool.java
2019独角兽企业重金招聘Python工程师标准>>> package redis.clients.jedis;import redis.clients.util.FixedReso ...
- Java源码详解二:HashMap源码分析--openjdk java 11源码
文章目录 HashMap.java介绍 1.HashMap的get和put操作平均时间复杂度和最坏时间复杂度 2.为什么链表长度超过8才转换为红黑树 3.红黑树中的节点如何排序 本系列是Java详解, ...
- Android-FixBug热修复框架的使用及源码分析(不发版修复bug)
前面几篇博文已经介绍了2种热修复框架的使用及源码分析,AndFix兼容性比较好,而Dexposed Art处于Beta版. AndFix和Dexposed都是阿里的开源项目. Alibaba-And ...
- 单例模式在JDK应用的源码分析
单例模式在JDK应用的源码分析 单例模式在jdk中的源码分析 在我们JDK中,java.lang.Runtime就是经典的单例模式(恶汉式) 代码分析+Debug源码+代码说明 public clas ...
- [转载]jQuery1.6.1源码分析系列
转载:http://www.cnblogs.com/nuysoft/archive/2011/11/14/2248023.html [原创] jQuery1.6.1源码分析系列(停止更新) 作者:nu ...
- 常用jdk类库源码分析以及各个包
常用jdk类库源码分析以及各个包 1.java.lang包 java.lang包 是Java中最常用的包,程序不需要注入,就可以使用该包中的类,利用包中的类可以设计最基本的Java程序. 2.java ...
- android agps,Android应用开发Android GPS ——AGPS源码分析及配置
本文将带你了解Android应用开发Android GPS --AGPS源码分析及配置,希望本文对大家学Android有所帮助. " Android Framework GPS --AGPS ...
最新文章
- 在命令行导出MySQL数据到Excel
- 图片预览组件PhotoView
- 日志管理系统的重要性---怼死你的客户
- Java编程 的动态性,第 2部分: 引入反射--转载
- js 难点之call,apply实现
- JS 日期工具类-基于yDate
- 各种品牌进入Bios方式
- 【机器学习】支持向量机原理及例题详解
- Windows Server Raid磁盘阵列
- SLA是什么意思 ?
- Gartner点将分布式文件存储,浪潮存储缘何一鸣惊人?
- Spring基础学习(一)
- 群晖安装Calibre(含格式转换豆瓣元数据推送kindle)221211
- Unity3D游戏开发入门学习笔记
- 3月27日下午上完毛概后是一节体育课,这学期要考篮球和跳绳
- unity摄像机追踪屏幕抖动的问题
- linux需要wifi网络认证,无线802.1x认证简介及配置方法
- 程序修行从“拔刀术”到“万剑诀”
- verilog练习:hdlbits网站上的做题笔记(7)!强烈推荐!
- 单相交流调压电路matlab仿真,单相斩控式交流调压电路
热门文章
- python多次循环输出_函数的Python循环(多次将输出作为输入重用)
- java程序a-z b-y_有一行电文,以按下面规律译成密码: A---Z a---z B---Y b---Y C---X c---x …… 即第1个字母编程第26个字...
- oppor17android版本,OPPOR17ColorOS系统怎么样
- Java程序启动同时复制resources下文件到jar包同级目录
- 【camera】基于YOLO的车辆多维特征识别系统(车色,车品牌,车标,车型)与PYQT实现(课程设计)
- 读后感与机翻《从视频中推断力量和学习人类效用》
- knn 进行手写数字识别
- Linux那些事儿之我是Sysfs(9)sysfs文件系统模型
- char和uchar区别
- ATS 5.3.0中利用grep得到纯净的配置文件