美文网首页
Go语言中atomic包的应用

Go语言中atomic包的应用

作者: 坤_7a1e | 来源:发表于2018-05-16 16:40 被阅读0次

    sync/atomic包提供了原子操作的能力,直接有底层CPU硬件支持,因而一般要比基于操作系统API的锁方式效率高些;

    这些功能需要非常小心才能正确使用。 除特殊的底层应用程序外,同步更适合使用channel或sync包的功能。 通过消息共享内存; 不要通过共享内存进行通信。

    原子增值

        我们通过下面用例来了解下,原子增值跟普通增值的不同

            package main

            import (

            "fmt"

            "sync/atomic"

            "sync"

            )

            func main() {

                var sum uint32 = 200

                var wg sync.WaitGroup

                for i:=0; i< 30; i++ {

                    wg.Add(1)

                    go func() {

                        defer wg.Done()

                        atomic.AddUint32(&sum, 1)

                    }()

                }

                wg.Wait()

                fmt.Println(sum)

                for i:=0; i< 30; i++ {

                    wg.Add(1)

                    go func() {

                        defer wg.Done()

                        sum++

                    }()

                }

                wg.Wait()

                fmt.Println(sum)

        }

        将上面程序在工作机上编译,然后运行几次,你会发现第一个打印值固定不变,第二个值不固定

    CAS(Compare-And-Swap)比较并交换

    func CompareAndSwapInt32(addr *int32, old, newint32) (swappedbool)

    下面代码体现了三种情况:

        a.当addr地址指向变量的值不等于old

        b.当addr地址指向变量的值等于old,等于new

        c.当addr地址指向的变量值等于old,不等于new

        import (

            "fmt"

            "sync/atomic"

            "sync"

        )

        func main() {

            sum := uint32(10)

            rst := false

            var wg sync.WaitGroup

            for i := 0; i < 10; i++ {

            wg.Add(1)

            go func() {

                defer wg.Done()

                rst = atomic.CompareAndSwapUint32(&sum, 100, 200)

            }()

        }

        wg.Wait()

        fmt.Println(sum)

        fmt.Println(rst)

        rst1 := false

        sum1 := uint32(100)

        for i := 0; i < 10; i++ {

            wg.Add(1)

            go func() {

                defer wg.Done()

                rst1 = atomic.CompareAndSwapUint32(&sum1, 100, 100)

            }()

          }

        wg.Wait()

        fmt.Println(sum1)

        fmt.Println(rst1)

        rst2 := false

        sum2 := uint32(100)

        for i := 0; i < 10; i++ {

            wg.Add(1)

            go func() {

                defer wg.Done()

                rst2 = atomic.CompareAndSwapUint32(&sum2, 100, 200)

            }()

        }

        wg.Wait()

        fmt.Println(sum2)

        fmt.Println(rst2)

    }

    运行结果:

        10

        false

        100

        true

        200    

        false

    原子导出值

        package main

        import (

            "fmt"

            "sync/atomic"

            "sync"

        )

        func main() {

            sum := uint32(1020)

            rst := uint32(0)

            var wg sync.WaitGroup

            for i := 0; i < 10; i++ {

                    wg.Add(1)

                    go func() {

                            defer wg.Done()

                            rst = sum

                    }()

            }

            wg.Wait()

            fmt.Println(sum)

            fmt.Println(rst)

     }

    原子导入值

    package main

    import (

            "fmt"

            "sync/atomic"

            "sync"

    )

    func main() {

            rst := uint32(0)

            var wg sync.WaitGroup

            for i := 0; i < 10; i++ {

                    wg.Add(1)

                    go func() {

                            defer wg.Done()

                            atomic.StoreUint32(&rst, 160)

                    }()

            }

            wg.Wait()

            fmt.Println(rst)

    }

    原子交互

    package main

    import (

            "fmt"

            "sync/atomic"

            "sync"

    )

    func main() {

            rst := uint32(0)

            old := uint32(0)

            old = atomic.SwapUint32(&rst,  1234)

            fmt.Println(rst)

            fmt.Println(old)

            var wg sync.WaitGroup

            for i := 0; i < 10; i++ {

                    wg.Add(1)

                    go func() {

                            defer wg.Done()

                            old = atomic.SwapUint32(&rst,  1234)

                    }()

            }

            wg.Wait()

            fmt.Println(rst)

            fmt.Println(old)

    }

    运行结果

        1234

        0

        1234

        1234

    相关文章

      网友评论

          本文标题:Go语言中atomic包的应用

          本文链接:https://www.haomeiwen.com/subject/ldapdftx.html