zoukankan      html  css  js  c++  java
  • Go不安全编程

    场景一:对接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 系统中要运行多次才能拿到理想中的结果,好难受啊

  • 相关阅读:
    好用的 convert freestyle jenkins jobs to pipeline 插件使用
    MkDocs 搭建试用
    当前云安全问题&&一些想法
    asciidoctor 安装试用
    gradle asciidoc 使用
    apache phoenix 安装试用
    parceljs 基本使用———又一个前端构建工具
    tidb 集群扩容
    tidb 安装试用&&以及安装几个问题解决
    caddy quic 协议试用&& 几个问题
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/12163028.html
Copyright © 2011-2022 走看看