这里假设有两个进程:进程A和进程B,他们要共享一块物理内存:region_c(通过/dev/目录的tmpfs文件: ashmem_test),再具体点,譬如进程A就是camera进程,进程B就是H264的编码线程所在的进程。则一个camera的录像过程就是:进程A获取未压缩的yuv原始视频数据,并将该视频数据数据放置在共享内存region_c区域,然后通过内存共享,进程B可以直接从共享内存region_c区域取出未压缩的原始视频数据作为该编码进程的输入,进行编码。这样就避免了大量的数据在跨进程间的拷贝,从而结余了大量的cpu时间和物理内存空间。
下面是一个如何使用共享内存的一个简单列子,需要特别注意的有以下几点:
#include <sys/mman.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define SIZE_MAP 1024*4 #define FILE_NAME "/dev/__properties5__" int printf_buf(unsigned char * buf, int len) { int i; for(i =0; i<len; i++) { printf("buf[%d]:0x%x ",i,buf[i]); if(!(i%4)) printf("\n"); } } int main(int argc, char * argv[]) { int ret = 0; int fd = 0; unsigned int i =0 ; unsigned char *buf = NULL; if(!strcmp(argv[1],"a")) //进程A { fd = open(FILE_NAME,O_RDWR | O_CREAT,0777); if(fd > 0) printf("open success fd:%d\n",fd); else printf("open failed\n"); lseek(fd,10,SEEK_SET); //注意必须要设置下文件的大小,如果文件大小是0,则不能映射 write(fd,"",1); buf = (unsigned char *) mmap(NULL,SIZE_MAP,PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); if (buf == MAP_FAILED) { printf("mmap failed for fd:%d\n",fd); close(fd); return -1; } printf("mmap success buf:%x \n",buf); printf_buf(buf, 50); //打印映射后初始化前的buf的内容 memset(buf,0x5a,SIZE_MAP);//设置映射后的buf的内容 close(fd); //关闭文件句柄,并不清楚映射,映射只有在munmap或进程被终止时才会被拆除 for(i=0; i<20; i++) //设置映射后的buf的内容 { buf[i] = 'a'+i; } munmap(buf,SIZE_MAP); //拆除进程A的映射 printf("set share memory buf to 'a' for process A \n"); // do not close fd }else if(!strcmp(argv[1],"b")) //进程B { fd = open(FILE_NAME,O_RDWR); if(fd > 0) printf("open success\n"); else printf("open failed\n"); buf = (unsigned char *) mmap(NULL,SIZE_MAP,PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); //将内存映射到进程B if (buf == MAP_FAILED) { printf("mmap failed for fd:%d\n",fd); close(fd); return -1; } close(fd); //关闭文件句柄,并不清除映射,映射只有在munmap或进程被终止时才会被拆除 printf("mmap for process B success,buf:%x\n",buf); printf("printf share memory for process B\n"); printf_buf(buf, 50);//打印共享内存的内容,在进程B中 munmap(buf,SIZE_MAP);//拆除进程B的映射 printf("completed\n"); }else { printf("please inpu the correct parameter:\n"); printf("shmem a \n"); printf("or \n"); printf("shmem b \n"); } return 0; }
rubbitxiao@szmce15:~/test/share_memory$ rm -rf shmem
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$ gcc -o shmem shmem.c
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$ ls -l
total 24
-rwxrwxr-x 1 rubbitxiao rubbitxiao 13070 Dec 8 20:51 shmem
-rwxr--r-- 1 rubbitxiao rubbitxiao 2447 Dec 8 20:50 shmem.c
-rw-rw-r-- 1 rubbitxiao rubbitxiao 3000 Dec 8 18:13 shmem.o
rubbitxiao@szmce15:~/test/share_memory$ sudo ./shmem a
open success fd:3
mmap success buf锛歝b52d000
buf[0]:0x0
buf[1]:0x0 buf[2]:0x0 buf[3]:0x0 buf[4]:0x0
buf[5]:0x0 buf[6]:0x0 buf[7]:0x0 buf[8]:0x0
buf[9]:0x0 buf[10]:0x0 buf[11]:0x0 buf[12]:0x0
buf[13]:0x0 buf[14]:0x0 buf[15]:0x0 buf[16]:0x0
buf[17]:0x0 buf[18]:0x0 buf[19]:0x0 buf[20]:0x0
buf[21]:0x0 buf[22]:0x0 buf[23]:0x0 buf[24]:0x0
buf[25]:0x0 buf[26]:0x0 buf[27]:0x0 buf[28]:0x0
buf[29]:0x0 buf[30]:0x0 buf[31]:0x0 buf[32]:0x0
buf[33]:0x0 buf[34]:0x0 buf[35]:0x0 buf[36]:0x0
buf[37]:0x0 buf[38]:0x0 buf[39]:0x0 buf[40]:0x0
buf[41]:0x0 buf[42]:0x0 buf[43]:0x0 buf[44]:0x0
buf[45]:0x0 buf[46]:0x0 buf[47]:0x0 buf[48]:0x0
buf[49]:0x0 set share memory buf to 'a' for process A
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$
rubbitxiao@szmce15:~/test/share_memory$ sudo ./shmem b
open success
mmap for process B success,buf:25647000
printf share memory for process B
buf[0]:0x61
buf[1]:0x62 buf[2]:0x63 buf[3]:0x64 buf[4]:0x65
buf[5]:0x66 buf[6]:0x67 buf[7]:0x68 buf[8]:0x69
buf[9]:0x6a buf[10]:0x6b buf[11]:0x6c buf[12]:0x6d
buf[13]:0x6e buf[14]:0x6f buf[15]:0x70 buf[16]:0x71
buf[17]:0x72 buf[18]:0x73 buf[19]:0x74 buf[20]:0x5a
buf[21]:0x5a buf[22]:0x5a buf[23]:0x5a buf[24]:0x5a
buf[25]:0x5a buf[26]:0x5a buf[27]:0x5a buf[28]:0x5a
buf[29]:0x5a buf[30]:0x5a buf[31]:0x5a buf[32]:0x5a
buf[33]:0x5a buf[34]:0x5a buf[35]:0x5a buf[36]:0x5a
buf[37]:0x5a buf[38]:0x5a buf[39]:0x5a buf[40]:0x5a
buf[41]:0x5a buf[42]:0x5a buf[43]:0x5a buf[44]:0x5a
buf[45]:0x5a buf[46]:0x5a buf[47]:0x5a buf[48]:0x5a
buf[49]:0x5a completed
rubbitxiao@szmce15:~/test/share_memory$ ^C
rubbitxiao@szmce15:~/test/share_memory$