golang操作共享内存

golang操作共享内存


上代码

/*
#include <sys/shm.h>
#include <stdlib.h>
static int shmflag=IPC_CREAT|0640;
*/
import "C"
//打开共享内存通过文件特征id(不存在则创建共享内存,但是文件一定得在,得靠它的特征码),如果文件路径和gendid相同,那你打开的共享内存就是同一个
func CreateShare_Mem[T int | int32 | int64](pathname string, gendid int, dst_ptr **T) uintptr {
	pn := C.CString(pathname)
	key := C.ftok(pn, (C.int)(gendid))
	C.free(unsafe.Pointer(pn))
	var te T
	shmid, _, err := syscall.Syscall(syscall.SYS_SHMGET, uintptr(key), unsafe.Sizeof(te), 01000|0640)
	if err != 0 {
		fmt.Println("[error]", err.Error())
		return 0
	}
	var sharemem uintptr
	sharemem, _, err = syscall.Syscall(syscall.SYS_SHMAT, shmid, 0, 0)
	if err != 0 {
		fmt.Println("[error]", err.Error())
		return 0
	}
	*dst_ptr = (*T)(unsafe.Pointer(sharemem))
	return shmid

}
//通过共享内存id来打开共享内存(前提是你的共享内存存在)
func GetShare_Mem[T int | int32 | int64](shmid int, dst_ptr **T) uintptr {
	shm, _, err := syscall.Syscall(syscall.SYS_SHMAT, uintptr(shmid), 0, 0)
	if len(err.Error()) < 1 {
		*dst_ptr = (*T)(unsafe.Pointer(shm))
		return 0
	}
	return shm
}
//关闭共享内存
func Close_Share_Mem(shm uintptr) error {
	_, _, err := syscall.Syscall(syscall.SYS_SHMDT, shm, 0, 0)
	if len(err.Error()) > 0 {
		return fmt.Errorf(err.Error())
	}
	return nil
}

在系统中查看共享内存

ipcs -m #查看系统中现有的共享内存
ipcrm -m shmid #删除共享内存,shmid为共享内存id号

POSIX共享内存操作
posix 在mac和freebsd上跑shm_open可能会出问题,可以自行换为传统的open方法,shm_open父目录为/dev/shm。不同进程打开相同共享内存需要指定相同的文件,并且相同的size

/*
#include <stdio.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <fcntl.h>
void* open_shm(char* pathname,int sizes){
	int shmid=shm_open(pathname,O_RDWR|O_CREAT,0640);
	if (shmid>0){
		if(ftruncate(shmid,sizes)!=-1){
			void* ans=mmap(NULL,sizes,PROT_READ|PROT_WRITE,MAP_SHARED,shmid,0);
			if(ans!=MAP_FAILED){
				return ans;
			}else{
				fprintf(stderr,"mmap failed\n");
			}
		}else{
			fprintf(stderr,"ftruncate failed\n");
		}
	}else{
		fprintf(stderr,"open shmid failed\n");
	}
	return 0;
}
void unmap(void* src,int sizes){
	msync(src,sizes,MS_SYNC);
	munmap(src,sizes);
}
*/
func Shm_Open[T int | int32 | int64](pathname string, dst **T) unsafe.Pointer {
	pathinfo := C.CString(pathname)
	var te T
	ansptr := C.open_shm(pathinfo, (C.int)(unsafe.Sizeof(te)))
	if ansptr != nil {
		*dst = (*T)(unsafe.Pointer(ansptr))
	}
	C.free(unsafe.Pointer(pathinfo))
	return ansptr
}

// posix share memory close interface
func Shm_Close(ptr unsafe.Pointer, sizes int) {
	C.unmap(ptr, (C.int)(sizes))
}

// posix share memory delete interface
func Shm_Del(shm_name string) {
	shm_cname := C.CString(shm_name)
	C.shm_unlink(shm_cname)
	C.free(unsafe.Pointer(shm_cname))
}

github 代码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值