golang中的原子操作在sync/atomic package中。

下文以比较和交换操作函数为例,介绍其使用。

CompareAndSwapInt32

比较和交换操作是原子性的。

// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)

判断参数addr指向的值是否与参数old的值相等,

如果相等,用参数new的新值替换掉addr存储的旧值,否则操作就会被忽略。

交换成功,返回true.

example1

package main

import (
"fmt"
"sync/atomic"
) func main(){ var value int32 fmt.Println("origin value:", value) swapFlag := atomic.CompareAndSwapInt32(&value, 0, 1) if swapFlag {
fmt.Println("swap, value:", value)
} else {
fmt.Println("not swap, value:", value)
} }

上面的代码是简单使用举例。

判断value中的值是否为0,如果是,则将1存储到value的地址中;否则,不做任何操作。

output:

origin value: 0

swap, value: 1

examaple2

下面例子中,有两个goroutine去更新同一地址存储的值,只有一个会操作成功。

package main

import (
"fmt"
"sync/atomic"
"time"
) func main(){
var value int32
fmt.Println("origin value:", value) go entry("1", &value) go entry("2", &value) time.Sleep(time.Second)
} func entry(name string, value *int32) { swapFlag := atomic.CompareAndSwapInt32(value, 0, 1) if swapFlag {
fmt.Println("goroutine name:",name, ", swap, value:", *value)
} else {
fmt.Println("goroutine name:", name, ", not swap, value:", *value)
} }

创建两个goroutine,两个goroutine执行相同的流程,同时去更新value。

其中一个会操作成功。

主goroutine等待两个goroutine结束。

output:

origin value: 0

goroutine name: 2 , swap, value: 1

goroutine name: 1 , not swap, value: 1

参考

https://www.kancloud.cn/digest/batu-go/153537

http://ifeve.com/go-concurrency-atomic/

golang 原子操作函数的更多相关文章

  1. golang的函数

    在golang中, 函数是第一类值(first-class object), 即函数可以赋值与被赋值. 换言之, 函数也可以作为ReceiverType, 定义自己的method. 实例: http. ...

  2. golang(06)函数介绍

    原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民 ...

  3. golang笔记——函数与方法

    如果你遇到没有函数体的函数声明,表示该函数不是以Go实现的. package math func Sin(x float64) float //implemented in assembly lang ...

  4. gcc提供的原子操作函数

    gcc从4.1.2提供了__sync_*系列的built-in函数,用于提供加减和逻辑运算的原子操作.其声明如下: type __sync_fetch_and_add (type *ptr, type ...

  5. Golang tips ----- 函数

    1.在函数调用时,Golang没有默认参数值 2.一个函数声明如果没有函数体,表面该函数不是由Golang实现的,这样的声明定义了函数标识符 3.拥有函数名的函数只能在包级语法块中被声明 4.函数值( ...

  6. Golang之函数练习

    小例题: package main import "fmt" /* 函数练习, 可变参数使用 写一个函数add 支持1个或多个int相加,并返回相加结果 写一个函数concat,支 ...

  7. [golang note] 函数定义

    普通函数定义 √ golang函数基本组成:关键字func.函数名.参数列表.返回值.函数体和返回语句. • 语法如下 func 函数名(参数列表) (返回值列表) { // 函数体 } • 示例如下 ...

  8. golang中函数类型

    今天看Martini文档,其功能列表提到完全兼容http.HandlerFunc接口,就去查阅了Go: net/http的文档,看到type HandlerFunc这部分,顿时蒙圈了.由于之前学习的时 ...

  9. golang:函数总结

    golang保留的函数 init(), main()是golang的保留函数,有如下特点: main() 只能用在main包中,仅可定义一个,init() 可定义任意包,可重复定义,建议只定义一个 两 ...

随机推荐

  1. c# GetType()和typeof()的区别

    c#   GetType()和typeof()的区别 C#中任何对象都具有GetType()方法,返回Type类型的当前对象的类型. GetType()是基类System.Object的方法,因此只有 ...

  2. KB/MB/GB。。单位换算

    今天遇到一个需求,需要把数据单位进行换算,记录一下.写的不好请勿见怪. function bytesToSize( bytes ) {//单位转化         var k = 1024,      ...

  3. 第七十四课 图的遍历(BFS)

    广度优先相当于对顶点进行分层,层次遍历. 在Graph.h中添加BFS函数: #ifndef GRAPH_H #define GRAPH_H #include "Object.h" ...

  4. Django之模型层-单表操作

    单表操作 添加记录 方式1 # 先实例化models中的对象,按照定义的语句规则传入参数,然后使用对象调用save()保存到数据库 book_obj = Book(id=1,title='python ...

  5. Java栈的简单实现

    * 数据结构与算法Java实现 栈 * * @author 小明 * */ public class MyStack { private Node top;// 头指针 int size;// 长度 ...

  6. HDU - 5130 :Signal Interference (多边形与圆的交)

    pro:A的监视区域是一个多边形. 如果A的监视区的内满足到A的距离到不超过到B的距离的K倍的面积大小.K<1 sol:高中几何体经验告诉我们满足题意的区域是个圆,那么就是求圆与多边形的交. # ...

  7. 【转】matlab的textscan与textread区别

    1.基本语法textscan的基本语法是:C = textscan(fid, 'format') C = textscan(fid, 'format', N) 其中fid为fopen命令返回的文件标识 ...

  8. 阿里druid数据库连接池缓存方案

    阿里缓存机制:若在进某一页面的时候执行了select语句,会将该select语句查询出来的数据存入缓存,若执行了修改语句则清空该缓存,若没有执行修改语句则再次进入此页面的时候会直接从缓存中加载上次se ...

  9. Damped Track 阻尼跟随

    Damped Track 阻尼跟随 https://www.youtube.com/watch?v=pd1od5WPCUw 2个网格及对应的2个空对象Z轴方向网格:{O.up}; 上方园孔把手中间放空 ...

  10. sql表连接方式

    表连接有几种? sql表连接分成外连接.内连接和交叉连接.   一.外连接 概述: 外连接包括三种,分别是左外连接.右外连接.全外连接. 对应的sql关键字:LEFT/RIGHT/FULL OUTER ...