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. 复习回顾(String,StringBuffer,Arrays方法总结)

    String: String类的对象是一经创建就无法变动内容的字符串常量,创建String类的对象可以使用直接赋值和利用构造方法赋值 String str=“hello”;  String str=n ...

  2. Transport & Buffer

    Transport 传输API的核心是Channel接口,用于所有的出站操作. 每个Channel都会分配一个ChannelPipeline和ChannelConfig.ChannelConfig负责 ...

  3. 为什么说Java中只有值传递?

    一.为什么说Java中只有值传递? 对于java中的参数传递方式中是否有引用传递这个话题,很多的人都认为Java中有引用传递,但是我个人的看法是,Java中只有值传递,没有引用传递. 那么关于对象的传 ...

  4. Error Downloading Packages: yum更新出现错误

    yum  install lrzsz 失败报错: 解决思路: 1:执行yum clean all 清除缓存目录下的软件包及旧的headers: 2:接着执行 yum list 重新列出所有已经安装和可 ...

  5. css完成下图

    <div></div> div{ height: 48px; width: 80px; padding: 0 16px 0 32px; background: rgba(0,0 ...

  6. ideal通过svn上传项目和激活方式

    激活方式: http://www.ideadev.club/topic/detail/102?anchor=1526259147353#1526259147353

  7. BinarySearch(Java)

    private int binarySearch(int[] input, int target) { if (input == null) { return -1; } int index1 = 0 ...

  8. java知识整理

    整理一下Java知识点. 一.final finally finalize区别 1.final 修饰符(关键字).被final修饰的类,不能再派生出新的子类,不能作为父类而被子类继承.因此一个类不能既 ...

  9. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  10. javascript的一些常用知识点

    1. 查看你的html文档中一共有多少个节点 :   document.getElementsByTagName(" * ").length; 2.  document.getEl ...