共享内存实例

POSIX 为创建、映射、同步和取消共享内存段提供五个入口点:

  • shm_open:创建共享内存段或连接到现有的已命名内存段。这个系统调用返回一个文件描述符。
  • shm_unlink():根据(shm_open() 返回的)文件描述符,删除共享内存段。实际上,这个内存段直到访问它的所有进程都退出时才会删除,这与在 UNIX 中删除文件很相似。但是,调用 shm_unlink() (通常由原来创建共享内存段的进程调用)之后,其他进程就无法访问这个内存段了。
  • mmap():把共享内存段映射到进程的内存。这个系统调用需要 shm_open() 返回的文件描述符,它返回指向内存的指针。(在某些情况下,还可以把一般文件或另一个设备的文件描述符映射到内存。对这些操作的讨论超出了本文的范围;具体方法请查阅操作系统的 mmap() 文档。)
  • munmap():作用与 mmap() 相反。
  • msync():用来让共享内存段与文件系统同步 — 当把文件映射到内存时,这种技术有用。
mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。 
  注:实际上,mmap()系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。 
  1、mmap()系统调用形式如下: 
  void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset ) 
  参数fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的进程间通信)。len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。prot 参数指定共享内存的访问权限。可取如下几个值的或:PROT_READ(可读) , PROT_WRITE (可写), PROT_EXEC (可执行), PROT_NONE(不可访问)。flags由以下几个常值指定:MAP_SHARED , MAP_PRIVATE , MAP_FIXED,其中,MAP_SHARED , MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用。offset参数一般设为0,表示从文件头开始映射。参数addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址。这里不再详细介绍mmap()的参数,读者可参考mmap()手册页获得进一步的信息。 

实例:写入端
#include <iostream>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
using namespace std;

int main(int argc, char *argv[])
{
	const char *name = "shm_name";
    int fd = shm_open(name, O_CREAT|O_RDWR, 0666);
	if(fd < 0)
	{
		fprintf(stderr, "shm_open\n");
		return -1;
	}
	ftruncate(fd, 100);
	char *ptr = (char*)mmap(0, 100, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if(ptr == NULL)
	{
		fprintf(stderr, "mmap\n");
		return -1;
		
	}
	strcpy(ptr, "hahahaha");
	munmap(ptr, strlen(ptr));
    return 0;
}
g++ shareserv.cpp -o shareserv -lrt
读出端:
#include <iostream>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
using namespace std;

int main(int argc, char *argv[])
{
	const char *name = "shm_name";
    int fd = shm_open(name, O_CREAT|O_RDWR, 0666);
	if(fd < 0)
	{
		fprintf(stderr, "shm_open\n");
		return -1;
	}
	ftruncate(fd, 100);
	char *ptr = (char*)mmap(0, 100, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if(ptr == NULL)
	{
		fprintf(stderr, "mmap\n");
		return -1;
		
	}
	printf("%s\n", ptr);
	munmap(ptr, strlen(ptr));
    return 0;
}
g++ sharecli.cpp -o sharecli -lrt
必须加上 -lrt ,否则编译出错

你可能感兴趣的:(mmap,shm_open)