如下是源代码实现直接编译即可使用:
//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))
}