• golang语言中sync/atomic包的学习与使用


    package main;

     
    import (
        "sync/atomic"
        "fmt"
        "sync"
    )
     
    //atomic包提供了底层的原子级内存操作
    //类型共有六种:int32, int64, uint32, uint64, uintptr, unsafe.Pinter
    //操作共五种:增减, 比较并交换, 载入, 存储,交换
     
    func main() {
     
        //增减操作
        var a int32;
        fmt.Println("a : ", a);
        //函数名以Add为前缀,加具体类型名
        //参数一,是指针类型
        //参数二,与参数一类型总是相同
        //增操作
        new_a := atomic.AddInt32(&a, 3);
        fmt.Println("new_a : ", new_a);
        //减操作
        new_a = atomic.AddInt32(&a, -2);
        fmt.Println("new_a : ", new_a);
     
        //CAS(Compare And Swap)比较并交换操作
        //函数名以CompareAndSwap为前缀,并具体类型名
        var b int32;
        fmt.Println("b : ", b);
        //函数会先判断参数一指向的值与参数二是否相等,如果相等,则用参数三替换参数一的值。
        //最后返回是否替换成功
        atomic.CompareAndSwapInt32(&b, 0, 3);
        fmt.Println("b : ", b);
     
        //载入操作
        //当我们对某个变量进行读取操作时,可能该变量正在被其他操作改变,或许我们读取的是被修改了一半的数据。
        //所以我们通过Load这类函数来确保我们正确的读取
        //函数名以Load为前缀,加具体类型名
        var c int32;
        wg := sync.WaitGroup{};
        //我们启100个goroutine
        for i := 0; i < 100; i++ {
            wg.Add(1);
            go func() {
                defer wg.Done();
                tmp := atomic.LoadInt32(&c);
                if !atomic.CompareAndSwapInt32(&c, tmp, (tmp + 1)) {
                    fmt.Println("c 修改失败");
                }
            }();
        }
        wg.Wait();
        //c的值有可能不等于100,频繁修改变量值情况下,CAS操作有可能不成功。
        fmt.Println("c : ", c);
     
        //存储操作
        //与载入函数相对应,提供原子的存储函数
        //函数名以Store为前缀,加具体类型名
        var d int32;
        fmt.Println("d : ", d);
        //存储某个值时,任何CPU都不会都该值进行读或写操作
        //存储操作总会成功,它不关心旧值是什么,与CAS不同
        atomic.StoreInt32(&d, 666);
        fmt.Println("d : ", d);
     
        //交换操作
        //直接设置新值,返回旧值,与CAS不同,它不关心旧值。
        //函数名以Swap为前缀,加具体类型名
        var e int32;
        wg2 := sync.WaitGroup{};
        //我们启10个goroutine
        for i := 0; i < 10; i++ {
            wg2.Add(1);
            go func() {
                defer wg2.Done();
                tmp := atomic.LoadInt32(&e);
                old := atomic.SwapInt32(&e, (tmp + 1));
                fmt.Println("e old : ", old);
            }();
        }
        wg2.Wait();
        fmt.Println("e : ", e);
    }
  • 相关阅读:
    数据结构:图(Graph)
    数据结构:图(Graph)
    sql中的左右关联、全关联、自关联
    sql中的左右关联、全关联、自关联
    Mathematical Functions (TransactSQL)
    Mathematical Functions (TransactSQL)
    数据库中SQL实现某列的乘积(SqlSERVER)
    数据库中SQL实现某列的乘积(SqlSERVER)
    devexpress表格控件gridcontrol设置隔行变色、焦点行颜色、设置(改变)显示值、固定列不移动(附源码)
    devexpress表格控件gridcontrol设置隔行变色、焦点行颜色、设置(改变)显示值、固定列不移动(附源码)
  • 原文地址:https://www.cnblogs.com/smallleiit/p/10926272.html
Copyright © 2020-2023  润新知