大佬教程收集整理的这篇文章主要介绍了golang对共享内存的操作,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
不同进程间的内存是互相独立的,没办法直接互相操作对方内的数据,而共享内存则是靠操作系统提供的内存映射机制,让不同进程的一块地址空间映射到同一个虚拟内存区域上,使不同的进程可以操作到一块共用的内存块。共享内存是效率最高的进程间通讯机制,因为数据不需要在内核和程序之间复制。
共享内存用到的是系统提供的mmap函数,它可以将一个文件映射到虚拟内存的一个区域中,程序使用指针引用这个区域,对这个内存区域的操作会被回写到文件上,其函数原型如下:
void *R_700_11845@map(void *addr,size_t len,int prot,int flags,int fd,off_t offset);@H_403_7@
顺带介绍一下shm_open和shm_unlink两个函数:
shm_open()函数
功能: 打开或创建一个共享内存区
头文件: #include <sys/mman.h>
函数原形: int shm_open(const char *name,int oflag,mode_t modE);
返回值: 成功返回0,出错返回-1
参数:
name 共享内存区的名字
oflag 标志位
mode 权限位
参数解释:oflag参数必须含有O_RDONLY和O_RDWR标志,还可以指定如下标志:O_CREAT,O_EXCL或O_TRUNC.mode参数指定权限位,
它指定O_CREAT标志的前提下使用。shm_open的返回值是一个整数描述字,它随后用作mmap的第五个参数。
shm_unlink()函数
功能: 删除一个共享内存区
头文件: #include <sys/mman.h>
函数原形: int shm_unlink(const char *Name);
参数: name 共享内存区的名字
返回值: 成功返回0,出错返回-1
shm_unlink函数删除一个共享内存区对象的名字,删除一个名字仅仅防止后续的open,mq_open或sem_open调用取得成功。
可以参考此文章的介绍来进一步了解mmap等函数:http://www.cnblogs.com/polestar/archive/2012/04/23/2466022.html
可以利用golang调用cgo的方法实现c中的mmap。实验分为读和写两个程序,这样我们可以观察到读进程可以读到写进程写入共享内存的信息。
package main /* #cgo linux LDFLAGS: -lrt #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #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); } */ import "C" import ( "fmt" "unsafe" ) const SHM_NAME = "my_shm" const SHM_SIZE = 4 * 1000 * 1000 * 1000 type MyData struct { Col1 int Col2 int Col3 int } func main() { fd,err := C.my_shm_new(C.CString(SHM_Name)) if err != nil { fmt.Println(err) return } C.ftruncate(fd,SHM_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 } C.close(fd) data := (*MyData)(unsafe.Pointer(ptr)) data.Col1 = 100 data.Col2 = 876 data.Col3 = 8021 }@H_403_7@ shm_reader.go代码示例:package main /* #cgo linux LDFLAGS: -lrt #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int my_shm_open(char *Name) { return shm_open(name,O_RDWR,err := C.my_shm_open(C.CString(SHM_Name)) if err != nil { fmt.Println(err) return } ptr,0) if err != nil { fmt.Println(err) return } C.close(fd) data := (*MyData)(unsafe.Pointer(ptr)) fmt.Println(data) }@H_403_7@上面的程序映射了一块4G的虚拟内存,用来证明mmap没有实际占用4G内存,而是用到了虚拟内存。shm_writer创建好共享内存以后,往内存区域写入了一个结构体,shm_reader则读出一个结构体。
以上是大佬教程为你收集整理的golang对共享内存的操作全部内容,希望文章能够帮你解决golang对共享内存的操作所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。