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

  • 相关阅读:
    Java设计模式—单例模式
    Java集合框架
    Java进程和线程
    Java IO
    Java异常类
    Java面向对象—抽象类和接口
    Java面向对象—多态
    Java面向对象—继承
    Java面向对象
    Java基础语法
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/12163028.html
Copyright © 2011-2022 走看看