ImageVerifierCode 换一换
格式:DOCX , 页数:35 ,大小:499.99KB ,
资源ID:17235305      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17235305.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Android系统匿名共享内存Anonymous Shared MemoryC++调用接口分析Word文档格式.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Android系统匿名共享内存Anonymous Shared MemoryC++调用接口分析Word文档格式.docx

1、IMemoryBase定义了匿名共享内操作的接口,而MemoryHeapBase是作为Binder机制中的Server角色的,因此,它需要实现IMemoryBase接口,此外,MemoryHeapBase还继承了RefBase类。从前面一篇文章中,我们知道,继承了RefBase类的子类,它们的对象都可以结合Android系统的智能指针来使用,因此,我们在实例化MemoryHeapBase类时,可以通过智能指针来管理它们的生命周期。 再来看和Binder机制相关的这部分类的逻辑关系。从这篇文章中,我们知道,所有的Binder对象都必须实现IInterface接口,无论是Server端实体对象,还

2、是Client端引用对象,通过这个接口的asBinder成员函数我们可以获得Binder对象的IBinder接口,然后通过Binder驱动程序把它传输给另外一个进程。当一个类的对象作为Server端的实体对象时,它还必须实现一个模板类BnInterface,这里负责实例化模板类BnInterface的类便是BnMemoryHeap类了,它里面有一个重要的成员函数onTransact,当Client端引用请求Server端对象执行命令时,Binder系统就会调用BnMemoryHeap类的onTransact成员函数来执行具体的命令。当一个类的对象作为Server端的实体对象时,它还要继承于BB

3、inder类,这是一个实现了IBinder接口的类,它里面有一个重要的成员函数transact,当我们从Server端线程中接收到Client端的请求时,就会调用注册在这个线程中的BBinder对象的transact函数来处理这个请求,而这个transact函数会将这些Client端请求转发给BnMemoryHeap类的onTransact成员函数来处理。最后,ProcessState和IPCThreadState两个类是负责和Binder驱动程序打交道的,其中,ProcessState负责打开Binder设备文件/dev/binder,打开了这个Binder设备文件后,就会得到一个打开设备文

4、件描述符,而IPCThreadState就是通过这个设备文件描述符来和Binder驱动程序进行交互的,例如它通过一个for循环来不断地等待Binder驱动程序通知它有新的Client端请求到来了,一旦有新的Client端请求到来,它就会调用相应的BBinder对象的transact函数来处理。 本文我们主要是要关注和匿名共享内存业务相关的这部分类,即IMemoryBase和MemoryHeapBase类的实现,和Binder机制相关的这部分类的实现,可以参考一文。 IMemoryBase类主要定义了几个重要的操作匿名共享内存的方法,它定义在frameworks/base/include/bin

5、der/IMemory.h文件中:cpp view plain copy 在CODE上查看代码片派生到我的代码片class IMemoryHeap : public IInterface public: . virtual int getHeapID() const = 0; virtual void* getBase() const = 0; virtual size_t getSize() const = 0; 成员函数getHeapID是用来获得匿名共享内存块的打开文件描述符的;成员函数getBase是用来获得匿名共享内存块的基地址的,有了这个地址之后,我们就可以在程序里面直接访问这块共

6、享内存了;成员函数getSize是用来获得匿名共享内存块的大小的。 MemoryHeapBase类主要用来实现上面IMemoryBase类中列出来的几个成员函数的,这个类声明在frameworks/base/include/binder/MemoryHeapBase.h文件中:class MemoryHeapBase : public virtual BnMemoryHeap /* * maps memory from ashmem, with the given name for debugging */ MemoryHeapBase(size_t size, uint32_t flags

7、= 0, char const* name = NULL); /* implement IMemoryHeap interface */ virtual int getHeapID() const; virtual void* getBase() const; virtual size_t getSize() const;private: int mFD; size_t mSize; void* mBase; MemoryHeapBase类的实现定义在frameworks/base/libs/binder/MemoryHeapBase.cpp文件中,我们先来看一下它的构造函数的实现:Memor

8、yHeapBase:MemoryHeapBase(size_t size, uint32_t flags, char const * name) mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags), mDevice(0), mNeedUnmap(false) const size_t pagesize = getpagesize(); size = (size + pagesize-1) & (pagesize-1); int fd = ashmem_create_region(name = NULL ? MemoryHeapBase : n

9、ame, size); LOGE_IF(fd= 0) if (mapfd(fd, size) = NO_ERROR) if (flags & READ_ONLY) ashmem_set_prot_region(fd, PROT_READ); 这个构造函数有三个参数,其中size表示要创建的匿名共享内存的大小,flags是用来设置这块匿名共享内存的属性的,例如是可读写的还是只读的,name是用来标识这个匿名共享内存的名字的,可以传空值进来,这个参数只是作为调试信息使用的。 MemoryHeapBase类创建的匿名共享内存是以页为单位的,页的大小一般为4K,但是是可以设置的,这个函数首先通过get

10、pagesize函数获得系统中一页内存的大小值,然后把size参数对齐到页大小去,即如果size不是页大小的整数倍时,就增加它的大小,使得它的值为页大小的整数倍:const size_t pagesize = getpagesize();size = (size + pagesize-1) & 调整好size的大小后,就调用系统运行时库层的C接口ashmem_create_region来创建一块共享内存了:int fd = ashmem_create_region(name = NULL ? 这个函数我们在前面一篇文章中可以介绍过了,这里不再详细,它只要就是通过Ashmem驱动程序来创建一个匿

11、名共享内存文件,因此,它的返回值是一个文件描述符。 得到了这个匿名共享内存的文件描述符后,还需要调用mapfd成函数把它映射到进程地址空间去:status_t MemoryHeapBase:mapfd(int fd, size_t size, uint32_t offset) if (mFlags & DONT_MAP_LOCALLY) = 0) void* base = (uint8_t*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset); mBase = base; else mFD = fd; mSize = size

12、; return NO_ERROR; 一般我们创建MemoryHeapBase类的实例时,都是需要把匿名共享内存映射到本进程的地址空间去的,因此,这里的条件(mFlags & DONT_MAP_LOCALLY = 0)为true,于是执行系统调用mmap来执行内存映射的操作。void* base = (uint8_t*)mmap(0, size, 传进去的第一个参数0表示由内核来决定这个匿名共享内存文件在进程地址空间的起始位置,第二个参数size表示要映射的匿名共享内文件的大小,第三个参数PROT_READ|PROT_WRITE表示这个匿名共享内存是可读写的,第四个参数fd指定要映射的匿名共享

13、内存的文件描述符,第五个参数offset表示要从这个文件的哪个偏移位置开始映射。调用了这个函数之后,最后会进入到内核空间的ashmem驱动程序模块中去执行ashmem_map函数,这个函数的实现具体可以参考一文,这里就不同详细描述了。调用mmap函数返回之后,就得这块匿名共享内存在本进程地址空间中的起始访问地址了,将这个地址保存在成员变量mBase中,最后,还将这个匿名共享内存的文件描述符和以及大小分别保存在成员变量mFD和mSize中。 回到前面MemoryHeapBase类的构造函数中,将匿名共享内存映射到本进程的地址空间去后,还看继续设置这块匿名共享内存的读写属性:if (fd 上面调用

14、mapfd函数来映射匿名共享内存时,指定这块内存是可读写的,但是如果传进来的参数flags设置了只读属性,那么还需要调用系统运行时库存层的ashmem_set_prot_region函数来设置这块匿名共享内存为只读,这个函数定义在system/core/libcutils/ashmem-dev.c文件,有兴趣的读者可以自己去研究一下。 这样,通过这个构造函数,一块匿名共享内存就建立好了,其余的三个成员函数getHeapID、getBase和getSize就简单了:int MemoryHeapBase:getHeapID() const return mFD;void* MemoryHeapBa

15、se:getBase() const return mBase;size_t MemoryHeapBase:getSize() const return mSize; 接下来我们再来看一下MemoryHeapBase在Client端实现的类图: 这个类图中的类也是可以划分为两部分,一部分是和业务相关的,即跟匿名共享内存操作相关的类,包括BpMemoryHeap、IMemoryBase和RefBase三个类,另一部分是和Binder机制相关的,包括IInterface、BpInterface、BpRefBase、IBinder、BpBinder、ProcessState和IPCThreadSta

16、te七个类。 在和匿名共享内存操作相关的类中,BpMemoryHeap类是前面分析的MemoryHeapBase类在Client端进程的远接接口类,当Client端进程从Service Manager或者其它途径获得了一个MemoryHeapBase对象的引用之后,就会在本地创建一个BpMemoryHeap对象来代表这个引用。BpMemoryHeap类同样是要实现IMemoryHeap接口,同时,它是从RefBase类继承下来的,因此,它可以与智能指针来结合使用。 在和Binder机制相关的类中,和Server端实现不一样的地方是,Client端不需要实现BnInterface和BBinder

17、两个类,但是需要实现BpInterface、BpRefBase和BpBinder三个类。BpInterface类继承于BpRefBase类,而在BpRefBase类里面,有一个成员变量mRemote,它指向一个BpBinder对象,当BpMemoryHeap类需要向Server端对象发出请求时,它就会通过这个BpBinder对象的transact函数来发出这个请求。这里的BpBinder对象是如何知道要向哪个Server对象发出请深圳市的呢?它里面有一个成员变量mHandle,它表示的是一个Server端Binder对象的引用值,BpBinder对象就是要通过这个引用值来把请求发送到相应的Se

18、rver端对象去的了,这个引用值与Server端Binder对象的对应关系是在Binder驱动程序内部维护的。这里的ProcessSate类和IPCThreadState类的作用和在Server端的作用是类似的,它们都是负责和底层的Binder驱动程序进行交互,例如,BpBinder对象的transact函数就通过线程中的IPCThreadState对象来将Client端请求发送出去的。这些实现具体可以参考一文。 这里我们主要关注BpMemoryHeap类是如何实现IMemoryHeap接口的,这个类声明和定义在frameworks/base/libs/binder/IMemory.cpp文件

19、中:class BpMemoryHeap : public BpInterface BpMemoryHeap(const sp& impl); mutable volatile int32_t mHeapId; mutable void* mBase; mutable size_t mSize; 先来看构造函数BpMemoryHeap的实现:BpMemoryHeap:BpMemoryHeap(const sp impl) BpInterface(impl), mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false

20、) 它的实现很简单,只是初始化一下各个成员变量,例如,表示匿名共享内存文件描述符的mHeapId值初化为-1、表示匿名内共享内存基地址的mBase值初始化为MAP_FAILED以及表示匿名共享内存大小的mSize初始为为0,它们都表示在Client端进程中,这个匿名共享内存还未准备就绪,要等到第一次使用时才会去创建。这里还需要注意的一点,参数impl指向的是一个BpBinder对象,它里面包含了一个指向Server端Binder对象,即MemoryHeapBase对象的引用。 其余三个成员函数getHeapID、getBase和getSize的实现是类似的:int BpMemoryHeap:

21、assertMapped(); return mHeapId;void* BpMemoryHeap:size_t BpMemoryHeap: 即它们在使用之前,都会首先调用assertMapped函数来保证在Client端的匿名共享内存是已经准备就绪了的:void BpMemoryHeap:assertMapped() const if (mHeapId = -1) sp binder(const_cast(this)-asBinder();BpMemoryHeap heap(static_castassertReallyMapped(); if (heap-mBase != MAP_FAILED) Mutex:Autolock _l(mLock); mBase = heap-mBase; mSize = heap-mSize; android_atomic_write( dup( heap-mHeapId ), &mHeapId ); e

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1