首页 > 其他 > 详细

Go不安全编程

时间:2020-01-07 19:40:37      阅读:86      评论:0      收藏:0      [点我收藏+]

场景一:对接C程序

大多数都是用于外部C程序实现的一些高效的库进行叫交互式会用到unsafe

场景二:指针类型转换

“不安全”行为的危险性:go 语言中是不支持强制类型转换的,但是我们使用 unsafe 是可以把一个类型的指针强行转化为任意类型的指针的

package unsafet_test

import (
    "fmt"
    "sync"
    "sync/atomic"
    "testing"
    "time"
    "unsafe"
)

// 不合理转换
func TestUnsafe(t *testing.T) {
    i := 10
    f := *(*float64)(unsafe.Pointer(&i))
    t.Log(unsafe.Pointer(&i))
    t.Log(f)
}

// 合理的类型转换
type MyInt int

func TestConvert(t *testing.T) {
    a := []int{1, 2, 3, 4}
    b := *(*[]MyInt)(unsafe.Pointer(&a))
    t.Log(b)
}

// 指针原子类型操作
// 场景:并发读写共享缓存时,为了达到读与写的安全性
// 当写的时候我们写在一个新的内存地址,写完之后用原子操作
// 把读的指针指向新的内存地址
func TestAtomic(t *testing.T) {
    var shareBufPtr unsafe.Pointer // 共享内存地址
    writeDataFn := func() {
        var data []int
        for i := 0; i < 100; i++ {
            data = append(data, i)
        }
        //fmt.Println(unsafe.Pointer(&data))
        atomic.StorePointer(&shareBufPtr, unsafe.Pointer(&data))
    }
    readDataFn := func() {
        data := atomic.LoadPointer(&shareBufPtr)
        fmt.Println(data, *(*[]int)(data))
    }
    var wg sync.WaitGroup
    writeDataFn()
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            for i := 0; i < 10; i++ {
                writeDataFn()
                time.Sleep(time.Millisecond * 100)
            }
            wg.Done()
        }()
        wg.Add(1)
        go func() {
            for i := 0; i < 10; i++ {
                readDataFn()
                time.Sleep(time.Millisecond * 100)
            }
            wg.Done()
        }()
    }
}

上面代码中的最后一个测试程序,我在 win10 系统中要运行多次才能拿到理想中的结果,好难受啊

Go不安全编程

原文:https://www.cnblogs.com/wuyongqiang/p/12163028.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!