package shmqueue
|
|
import (
|
"reflect"
|
"unsafe"
|
)
|
|
// []byte struct
|
type ShmDataInfo struct {
|
Len uint32
|
Cache []byte
|
}
|
|
// shmData2Info convert []byte to *ShmDataInfo
|
func shmData2Info(b []byte) *ShmDataInfo {
|
return (*ShmDataInfo)(unsafe.Pointer(
|
(*reflect.SliceHeader)(unsafe.Pointer(&b)).Data,
|
))
|
}
|
|
const SHMSLICEOFFSET int = 32
|
// ConvertToSlice convert to []byte
|
func ptr2Slice(s unsafe.Pointer, size,cap int) []byte {
|
var x reflect.SliceHeader
|
x.Len = size
|
x.Cap = cap
|
x.Data = uintptr(s)
|
return *(*[]byte)(unsafe.Pointer(&x))
|
}
|
|
//WriteShmData data待写入的数据; shmId:共享内存id,只attach,不create
|
// 把data写入shmId对应的shm中, 流程: attach->写入数据->detach
|
// 适合shm是空的,解码使用
|
func WriteShmData(data []byte, shmId int) error {
|
shmData, err := Attach(shmId)
|
if err != nil {
|
return err
|
}
|
sdi := shmData2Info(shmData)
|
if len(data) <= len(shmData)-SHMSLICEOFFSET {
|
sdi.Len = uint32(len(data))
|
} else {
|
sdi.Len = uint32(len(shmData)-SHMSLICEOFFSET)
|
}
|
|
tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Len), len(shmData)-SHMSLICEOFFSET)
|
copy(tmpData, data)
|
|
err = Detach(shmData)
|
if err != nil {
|
return err
|
}
|
|
return nil
|
}
|
|
//ReadShmData attach到shmId对应的共享内存,并读出数据[]byte
|
// 使用之后需要detach
|
func ReadShmData(shmId int) ([]byte, error) {
|
shmData, err := Attach(shmId)
|
if err != nil {
|
return nil, err
|
}
|
|
sdi := shmData2Info(shmData)
|
tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Len), len(shmData)-SHMSLICEOFFSET)
|
|
return tmpData, nil
|
}
|
|
//DeepCopyDataToShm 深拷贝,把内存的数据拷贝attach之后共享内存中
|
// 输入: shmData是attach返回的[]byte, memdData是内存中的数据
|
// 写入数据到共享内存使用:attach->DeepCopyDataToShm->detach
|
// 适合解码使用
|
func DeepCopyDataToShm(memData,shmData []byte) {
|
sdi := shmData2Info(shmData)
|
if len(memData) <= len(shmData)-SHMSLICEOFFSET {
|
sdi.Len = uint32(len(memData))
|
} else {
|
sdi.Len = uint32(len(shmData)-SHMSLICEOFFSET)
|
}
|
|
tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Len), len(shmData)-SHMSLICEOFFSET)
|
copy(tmpData, memData)
|
}
|
|
//ReadShmData 把attach后的shmData转成内存data
|
// 输入:attach到共享内存得到的shmData
|
// 输出:转换后的data
|
// 从共享内存中读取数据使用:attach->ConvertShmToData->只读,业务处理结束后->detach
|
func ConvertShmToData(shmData []byte) []byte {
|
sdi := shmData2Info(shmData)
|
tmpData := ptr2Slice(unsafe.Pointer(&sdi.Cache), int(sdi.Len), len(shmData)-SHMSLICEOFFSET)
|
|
return tmpData
|
}
|
|
//UpdateDataToShm (类似浅拷贝)更新数据到共享内存
|
// 输入: ConvertShmToData得到的数据data,经过业务处理后,该数据有变化,需要update到shm里
|
// 更新数据到共享内存使用: attach->ConvertShmToData->修改data数据,业务处理结束后->UpdateDataToShm->detach
|
func UpdateDataToShm(data, shmData []byte) {
|
sdi := shmData2Info(shmData)
|
sdi.Len = uint32(len(data))
|
}
|