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

  • 相关阅读:
    HTML基础-3
    HTML基础-2
    HTML基础-1
    hdu 1709 The Balance(母函数)
    hdu 2082 找单词(母函数)
    hdu 1085 Holding Bin-Laden Captive!(母函数)
    hdu 1028 Ignatius and the Princess III(母函数)
    hdu 1027 Ignatius and the Princess II(正、逆康托)
    康托展开、康托逆展开原理
    hdu 4288 Coder(单点操作,查询)
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/12163028.html
Copyright © 2020-2023  润新知