什么是共享内存
共享内存是一种计算机系统中用于多个进程或线程之间共享数据的技术或机制。在共享内存中,多个进程或线程可以访问同一块内存区域,从而实现它们之间的数据共享。这使得进程或线程之间可以直接读取和写入共享内存中的数据,而无需通过其他通信机制(如管道、消息队列等)来进行数据传输。
通俗理解,共享内存,好似一款用内存做的磁盘,不同进程都可以访问和写入,因为通过系统API构建的一块内存空间,不属于任何一个进程,则自己的进程退出,数据依然保持。(由于是内存,系统重启数据当然会丢失)
Golang 创建并挂载共享内存
import (
"unsafe"
)
func bindShareMemory() unsafe.Pointer {
const memory_size = 2 * 1024 * 1024
var shareKey uintptr = 3
var readOnly = false
var address uintptr = 0
shmId, _, err := syscall.Syscall(syscall.SYS_SHMGET, shareKey, memory_size, 00001000|0600)
if err != 0 {
panic(err)
}
flags := uintptr(0x0)
if readOnly {
flags = uintptr(0x00001000)
}
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
}
问题解答
- 如果 操作系统已经存在了某个相同 shareKey, 但是memory_size 不同的情况,挂载会 异常,
也就是 shmId, _, err := syscall.Syscall(syscall.SYS_SHMGET, shareKey, memory_size, 00001000|0600)
这里的 err 将不会返回 0 值, 解决办法,需要删除操作系统之前的共享内存
共享内存相关 操作
ipcs -m
ipcrm -m 196608