日期:2014-05-16  浏览次数:20871 次

unix 共享内存 存储映射 注意与android中ashm的区别与联系
android ashm
http://blog.csdn.net/luoshengyang/article/details/6651971
用了aidl,服务实现后在server(bindService)组件的onCreate中注册到servicemanager: ServiceManager.addService("AnonymousSharedMemory", memoryService);注意,这个应用的Android.mk中有:LOCAL_CERTIFICATE := platform,所以能注册上。

luo说:匿名共享内存一般是结合Binder来使用,没有Binder,匿名共享内存也一样可以使用,只要你有办法将匿名共享内存的文件描述符从一个进程传到另外一个进程就可以了。就像使用unix共享内存一样。

http://blog.csdn.net/luoshengyang/article/details/6664554
http://blog.csdn.net/luoshengyang/article/details/6666491

1. MemoryFile.java::native_open -> cpp -> ashmem_create_region -> /dev/ashmem -> Ashmem驱动程序中创建了一个ashmem_area结构: struct ashmem_area, ashmem_area结构保存在打开文件结构体(file *)的private_data域.

2. MemoryFile.java::native_mmap -> cpp -> mmap(...,/dev/ashmem...) -> ashmem_mmap -> shmem_file_setup:
调用了Linux内核提供的shmem_file_setup函数来在临时文件系统tmpfs中创建一个临时文件,这个临时文件与Ashmem驱动程序创建的匿名共享内存对应。函数shmem_file_setup是Linux内核中用来创建共享内存文件的方法,而Linux内核中的共享内存机制其实是一种进程间通信(IPC)机制,它的实现相对也是比较复杂,Android系统的匿名共享内存机制正是由于直接使用了Linux内核共享内存机制,它才会很小巧,它站在巨人的肩膀上了。关于Linux内核中的共享内存的相关知识,可以参考前面Android学习启动篇一文中提到的一本参考书籍《Linux内核源代码情景分析》的第六章传统的Unix进程间通信第七小节共享内存。
        通过shmem_file_setup函数创建的临时文件vmfile最终就保存在vma->file中了。这里的vma是由Linux内核的文件系统层传进来的,它的类型为struct vm_area_struct,它表示的是当前进程空间中一块连续的虚拟地址空间,它的起始地址可以由用户来指定,也可以由内核自己来分配,这里我们从JNI方法native_mmap调用的mmap的第一个参数为NULL可以看出,这块连续的虚拟地址空间的起始地址是由内核来指定的。文件内存映射操作完成后,用户访问这个范围的地址空间就相当于是访问对应的文件的内容了。有关Linux文件的内存映射操作,同样可以参考前面Android学习启动篇一文中提到的一本参考书籍《Linux内核源代码情景分析》的第二章内存管理第十三小节系统调用mmap。从这里我们也可以看出,Android系统的匿名共享内存是在虚拟地址空间连续的,但是在物理地址空间就不一定是连续的了。
        同时,这个临时文件vmfile也会保存asma->file域中,这样,Ashmem驱动程序后面就可以通过在asma->file来操作这个匿名内存共享文件了。
        函数ashmem_mmap执行完成后,经过层层返回到JNI方法native_mmap中去,就从mmap函数的返回值中得到了这块虚拟空间的起始地址了,这个起始地址最终返回到应用程序框架层的MemoryFile类的构造函数中,并且保存在成员变量mAddress中,后面,共享内存的读写操作就是对这个地址空间进行操作了。

2. MemoryFile.java::native_read/write...

小结:ashmem与Unix的内存共享机制相似,都是在某个相对的虚拟文件系统中创建一个文件,然后将这个文件映射到用户进程空间中,从而对进程空间中的那块区域的读写以对底层文件的读写。
二者的区别是:
1. 它们的API不同:ashmem底层是一个驱动程序文件(/dev/ashmem),调用的系统调用是mmap(对应驱动中的相应函数ashmem_mmap,ashmem_mmap再去调用shmem_file_setup函数创建了临时文件vmfile。。。),Unix共享内存的api是shmget和shmat(attach即将内核相应的结构或文件映射用户进程空间)。
2. ashmem底层是一个驱动程序,而Unix中的暂不清楚如何实现。

另外:ashmem与mmap的区别:一个是驱动文件,一个是系统调用。mmap就是将一个文件映射到用户进程空间的一块区域,所以它本身就是ashmem机制的一部份,但不是全部。

(end)


Unix/Linux下的IPC---共享内存  (来自:http://bdxnote.blog.163.com/blog/static/844423520100105258311/)

2010-01-10 17:25:08|  分类: C/VC/C++ |字号 订阅
共享内存指的是:把所有需要使用的共享数据都存放在共享内存(IPC shared memory region)区域中,任何想要访问这些共享数据的进程都必须在自己的进程地址空间中新增加一块内存区域,用来映射存放共享数据的物理内存页面;也就是说,任何想要访问这些共享数据的进程都必须把存放共享数据的物理内存页面的全部地址空间都映射到自己的进程地址空间中;这就是System V共享内存的实现机制;
系统调用mmap()通过映射一个普通文件来实现共享内存;而System V则是通过映射特殊文件系统shm中的一个文件来实现进程间共享内存通信的;也就是说,每个共享内存区域都对应特殊文件系统shm中的一个文件(通过struct shmid_kernel结构来关联起来的);
一、System V共享内存的原理:
进程间需要共享的数据存放在一个叫做IPC共享内存区域的地方,所有需要访问这些共享数据的进程都要把存放这些共享数据的共享内存区域以及所对应的物理内存页面的全部地址空间都映射到自己的进程地址空间中.System V共享内存通过系统调用shmget()来获得或创建一个IPC共享内存区域,并返回这个共享内存区域的唯一标识符.内核在保证系统调用shmget()获得或创建一个共享内存区域,并初始化该共享内存区域对应的shmid_kernel结构的同时,还将在特殊文件系统shm中创建或打开一个同名的文件,并在内存中建立起该文件的struct dentry和struct inode结构,新建的文件不属于任何一个进程(任何进程够可以访问该共享内存区域).所有这一切操作都是系统调用shmget()完成的;
注意:每一个共享内存区域都有一个控制结构:struct shmid_kernel,shmid_kernel结构是共享内存区域中非常重要的一个结构,它是把存储管理与文件系统结合起来的桥梁;struct shmid_kernel结构的定义如下:
struct shmid_kernel
{
  struct kern_ipc_perm  shm_perm;
  struct file*          shm_file;
  int                   id;
  unsigned long         shm_nattch;
  unsigned long