golang 结合cgo 操作共享内存,包括虚拟内存mmap版和内存shm版

来源:互联网 发布:成勘院待遇怎么样 知乎 编辑:程序博客网 时间:2024/06/03 03:18

如下是源代码实现直接编译即可使用:

//author sam by 20170621// 使用示例:// package utils// import (//  "fmt"//  u "lpaiche.com/utils"//  "testing"// )// type MyData struct {//  Col1 int//  Col2 int//  Col3 int//  Col4 int// }// //-----------------------------------------test_mmap_shm----------------------------// func TestWriteMmapShm(t *testing.T) {//  shm := u.NewShmMmap("test")//  fmt.Println(shm)//  fmt.Println("写入共享内存")//  data := (*MyData)(shm.GetWritePointer())//  data.Col1 = 105//  data.Col2 = 276//  data.Col3 = 2021//  data.Col4 = 2020//  fmt.Println(data)// }// func TestReadMmapShm(t *testing.T) {//  fmt.Println("读取共享内存")//  shm := u.NewShmMmap("test")//  data1 := (*MyData)(shm.GetReadPointer())//  fmt.Println(data1)// }// func TestFreeMmapShm(t *testing.T) {//  fmt.Println("删除共享内存")//  shm := u.NewShmMmap("test")//  shm.Remove()// }// //-------------------------------------------test_mem_shm------------------------// func TestShmmemGetWritePointer(t *testing.T) {//  shm := u.NewShmMem("/tmp/shm")//  fmt.Println(shm)//  data := (*MyData)(shm.GetWritePointer())//  defer shm.Close()//  data.Col1 = 1111//  data.Col2 = 2222//  data.Col3 = 3333//  data.Col4 = 4444//  fmt.Println(data)// }// func TestShmmemGetReadPointer(t *testing.T) {//  fmt.Println("读取共享内存")//  shm := u.NewShmMem("/tmp/shm")//  data1 := (*MyData)(shm.GetReadPointer())//  fmt.Println(data1)// }// func TestShmmemRemove(t *testing.T) {//  shm := u.NewShmMem("/tmp/shm")//  fmt.Println("删除共享内存")//  shm.Remove()// }package utils/*#cgo linux LDFLAGS: -lrt#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/shm.h>#include <sys/ipc.h>//-----------------cgo_mmap----------------------------#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)int my_shm_new(char *name) {    //shm_unlink(name);    return shm_open(name, O_RDWR|O_CREAT|O_EXCL, FILE_MODE);}int my_shm_open(char *name) {    return shm_open(name, O_RDWR, FILE_MODE);}void my_shm_free(char *name){    shm_unlink(name);}//------------------cgo_shm-------------------------int my_shmmem_open(char *file,int size,int open_flag){    int shm_id;    key_t key;    key = ftok(file, 0x111);    if(key == -1){        return -1;    }    if(open_flag)        shm_id = shmget(key, size, IPC_CREAT|IPC_EXCL|0600);    else        shm_id = shmget(key, 0, 0);    if(shm_id == -1){        return -1;    }    return shm_id;}int my_shmmem_rm(int shm_id){    shmctl(shm_id, IPC_RMID, NULL);    return 0;}*/import "C"import (    "fmt"    "unsafe")//------------------------------mmap实现共享内存操作-------------------------------------------------------------type ShmMmap struct {    name string    size int}func NewShmMmap(shm_name string, shm_size ...int) *ShmMmap {    shm_size1 := 1 * 1000 * 1000 * 1000 //默认共享内存大小1G    if shm_size != nil {        shm_size1 = shm_size[0]    }    shmm := ShmMmap{name: shm_name, size: shm_size1}    return &shmm}func (this *ShmMmap) GetWritePointer() unsafe.Pointer {    this.Remove()    fd, err := C.my_shm_new(C.CString(this.name))    if err != nil {        fmt.Println(err)        return nil    }    shm_size := (C.__off_t)(this.size)    C.ftruncate(fd, shm_size)    ptr, err := C.mmap(nil, 4*1000*1000*1000, C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED, fd, 0)    if err != nil {        fmt.Println(err)        return nil    }    C.close(fd)    return (unsafe.Pointer(ptr))}func (this *ShmMmap) Remove() {    C.my_shm_free(C.CString(this.name))}func (this *ShmMmap) GetReadPointer() unsafe.Pointer {    fd, err := C.my_shm_open(C.CString(this.name))    if err != nil {        fmt.Println(err)        return nil    }    shm_size := (C.size_t)(this.size)    ptr, err := C.mmap(nil, shm_size, C.PROT_READ|C.PROT_WRITE, C.MAP_SHARED, fd, 0)    if err != nil {        fmt.Println(err)        return nil    }    C.close(fd)    return (unsafe.Pointer(ptr))}//---------------------------------------shm实现共享内存操作------------------------------------------type ShmMem struct {    filename string    size     int    shmid    int    pointer  unsafe.Pointer}func NewShmMem(pathfilename string, shm_size ...int) *ShmMem {    shm_size1 := 4096 //默认共享内存大小4k    if shm_size != nil {        shm_size1 = shm_size[0]    }    shmm := ShmMem{filename: pathfilename, size: shm_size1, shmid: 0}    return &shmm}func (this *ShmMem) initShmit() {    filename := C.CString(this.filename)    defer C.free(unsafe.Pointer(filename))    this.shmid = int(C.my_shmmem_open(filename, C.int(this.size), C.int(1)))    if this.shmid < 0 {        this.shmid = int(C.my_shmmem_open(filename, C.int(this.size), C.int(0)))    }    if this.shmid < 0 {        fmt.Println("open share memery failed!")        Panic("open share memery failed! ")    }}func (this *ShmMem) GetWritePointer() unsafe.Pointer {    this.initShmit()    addr := C.shmat(C.int(this.shmid), nil, 0)    this.pointer = unsafe.Pointer(addr)    return this.pointer}func (this *ShmMem) GetReadPointer() unsafe.Pointer {    return this.GetWritePointer()}func (this *ShmMem) Close() {    C.shmdt(this.pointer)}func (this *ShmMem) Remove() {    this.initShmit()    C.my_shmmem_rm(C.int(this.shmid))}
原创粉丝点击