Golang 共享内存的使用

什么是共享内存

共享内存是一种计算机系统中用于多个进程或线程之间共享数据的技术或机制。在共享内存中,多个进程或线程可以访问同一块内存区域,从而实现它们之间的数据共享。这使得进程或线程之间可以直接读取和写入共享内存中的数据,而无需通过其他通信机制(如管道、消息队列等)来进行数据传输。
通俗理解,共享内存,好似一款用内存做的磁盘,不同进程都可以访问和写入,因为通过系统API构建的一块内存空间,不属于任何一个进程,则自己的进程退出,数据依然保持。(由于是内存,系统重启数据当然会丢失)

Golang 创建并挂载共享内存


import (
	"unsafe"
)

func bindShareMemory() unsafe.Pointer {
	// 声明需要创建共享内存的大小
	const memory_size = 2 * 1024 * 1024 // 这里 2M
	var shareKey uintptr = 3 // 自己定义共享内存的key
	var readOnly = false // 是否只读方式挂载
	var address uintptr = 0 // 共享内存地址,为0即可
	// 通过KEY, 获取一个共享内存,如果不存在会创建
	shmId, _, err := syscall.Syscall(syscall.SYS_SHMGET, shareKey, memory_size, 00001000|0600) // shmId 为共享内存的ID(操作系统构建返回
	
	if err != 0 {
		panic(err)
	}
	
	flags :=  uintptr(0x0)
	if readOnly {
		flags = uintptr(0x00001000) // 只读挂载
	}
	
	// 开始挂载共享内存, shmAddress为共享内存地址
	shmAddress, _, err2 := syscall.Syscall(syscall.SYS_SHMAT, shmId, address, flags)
	if err2 != 0 {
		panic(err2)
	}
	
	return unsafe.Pointer(shmAddress)
}

写入一个int类型的值,测试一下


func main() {
	pointer := bindShareMemory()
	lastInt := *(*int)(pointer)
	fmt.Printf("上一次写入数值: %v \n", lastInt)
	value := rand.Intn(12454123)
	fmt.Printf("这次写入数值: %v \n", value)
	*(*int)(pointer) = value // 先转换成 int指针在 解引用,这样对该内存块赋值
}

问题解答

  • 如果 操作系统已经存在了某个相同 shareKey, 但是memory_size 不同的情况,挂载会 异常,
    也就是 shmId, _, err := syscall.Syscall(syscall.SYS_SHMGET, shareKey, memory_size, 00001000|0600)这里的 err 将不会返回 0 值, 解决办法,需要删除操作系统之前的共享内存

共享内存相关 操作

  • 查询操作系统的共享内存
ipcs -m
  • 删除共享内存
ipcrm -m 196608
# 196608 为 shared memory ID
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值