很多事情看起来很简单,但是动起手来,发现会有很多问题我们刚开始没有考虑到的。我们知道LINUX下的一种进程间通信叫共享内存,也就是使用mmap来实现。
首先介绍一下mmap这个函数
http://linux.die.net/man/2/mmap
这个函数可以分为两种使用方式,一种是将文件映射,另一种就是内存映射。区别再于是否设置了MAP_ANONYMOUS,如果设置了这个flag,那么就意味着是内存映射,否则为文件映射。
1,文件映射,将这种方式认为是一种读写文件的方式。可以将文件通过mmap映射,然后就可以直接按照指针来读取内容,速度快一些,也方便一些。写文件就有点奇怪了,首先应该保证文件大小满足我们将要写进去的数据,否则将会发生BUS error。所以用这种方式应该是先创建一个文件,然后扩大这个文件的大小?还有一些网上的分析说,写完成后munmap不一定保证将数据完整写回磁盘。暗礁比较多,刚开始我用这种方式往里面写内容,按照设想,应该可以自动扩大文件大小,但是却得到错误。
2,内存映射,内存映射被认为是一种进程间通信的方式,但也确实不太好用吧?必须找一个合适的地址,然后大家一起来映射这个地址,如果映射失败了,那么就读写不一样的内存地址了,在读写的时候还得加上一个文件锁之类的?
我应该给自己新的编程方式叫做 小心编程,多思考,多判断。
以下是一段烂代码,测试用途。
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
static int gshmem_fd = -1;
void *shmem_alloc(size_t size)
{
void *addr;
/*gshmem_fd = open("/tmp/shmem", O_RDWR);
if(gshmem_fd < 0)
{
printf("Open failed.\n");
return NULL;
}*/
addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, gshmem_fd, 0);
printf("mmap success, addr=%p.\n", addr);
return addr;
}
void shmem_free(void *addr, size_t size)
{
munmap(addr, size);
close(gshmem_fd);
gshmem_fd = -1;
}
int main()
{
char *addr = NULL;
void *temp = NULL;
int size = 1024;
int i = 0;
temp = shmem_alloc(size);
if(MAP_FAILED == temp)
{
printf("shmem_alloc failed.\n");
return -1;
}
addr = (char *)temp;
for(; i < size - 1; i++)
{
*addr = 'a';
addr ++;
}
*addr = '\0';
printf("output:%s.\n", (char *)temp);
shmem_free(temp, size);
return 0;
}