Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(6)

简介:

   接下来,我们再来看看server模块的实现。在external/ashmem/common目录下,只有一个源文件SharedBufferServer.cpp,它实现了内存共享服务SharedBufferService:

  1. #define LOG_TAG "SharedBufferServer"  
  2.   
  3. #include <utils/Log.h>  
  4. #include <binder/MemoryBase.h>  
  5. #include <binder/MemoryHeapBase.h>  
  6. #include <binder/IServiceManager.h>  
  7. #include <binder/IPCThreadState.h>  
  8.   
  9. #include "../common/ISharedBuffer.h"  
  10.   
  11. class SharedBufferService : public BnSharedBuffer  
  12. {  
  13. public:  
  14.     SharedBufferService()  
  15.     {  
  16.         sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer");  
  17.         if(heap != NULL)  
  18.         {  
  19.             mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE);  
  20.   
  21.             int32_t* data = (int32_t*)mMemory->pointer();  
  22.             if(data != NULL)  
  23.             {  
  24.                 *data = 0;  
  25.             }  
  26.         }  
  27.     }  
  28.   
  29.     virtual ~SharedBufferService()  
  30.     {  
  31.         mMemory = NULL;  
  32.     }  
  33.   
  34. public:  
  35.     static void instantiate()  
  36.     {  
  37.         defaultServiceManager()->addService(String16(SHARED_BUFFER_SERVICE), new SharedBufferService());  
  38.     }  
  39.   
  40.     virtual sp<IMemory> getBuffer()  
  41.     {  
  42.         return mMemory;  
  43.     }  
  44.   
  45. private:  
  46.     sp<MemoryBase> mMemory;  
  47. };  
  48.   
  49. int main(int argc, char** argv)  
  50. {  
  51.     SharedBufferService::instantiate();  
  52.   
  53.     ProcessState::self()->startThreadPool();  
  54.     IPCThreadState::self()->joinThreadPool();  
  55.   
  56.     return 0;  
  57. }  
        SharedBufferService服务实现了BnSharedBuffer接口。在它的构造函数里面,首先是使用MemoryHeapBase类创建了一个匿名共享内存,大小为SHARED_BUFFER_SIZE。接着,又以这个MemoryHeapBase对象为参数,创建一个MemoryBase对象,这个MemoryBase对象指定要维护的匿名共享内存的的偏移位置为0,大小为SHARED_BUFFER_SIZE,并且,将这个匿名共享内存当作一个整型变量地址,将它初始化为0。最终,这个匿名共享内存对象保存在SharedBufferService类的成员变量mMemory中,这个匿名共享内存对象可以通过成员函数getBuffer来获得。
 
        在Server端应用程序的入口函数main中,首先是调用SharedBufferService静态成员函数instantiate函数来创建一个SharedBufferService实例,然后通过defaultServiceManager函数来获得系统中的Service Manager接口,最后通过这个Service Manager接口的addService函数来把这个SharedBufferService服务添加到Service Manager中去,这样,Client端就可以通过Service Manager来获得这个共享内存服务了。有关Service Manager的实现,请参考前面一篇文章 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路 ,而用来获取Service Manager接口的defaultServiceManager函数的实现可以参考另外一篇文章 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路 。初始化好这个共享内存服务之后,程序就通过ProcessState::self()->startThreadPool()函数来创建一个线程等待Client端来请求服务了,最后,程序的主线程也通过IPCThreadState::self()->joinThreadPool()函数来进入到等待Client端来请求服务的状态中。
       我们还需要为这个Server端应用程序编译一个编译脚本,在external/ashmem/server目录下,新建一个Android.mk文件,它的内容如下所示:
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE_TAGS :optional  
  6.   
  7. LOCAL_SRC_FILES := ../common/ISharedBuffer.cpp \  
  8.         SharedBufferServer.cpp  
  9.   
  10. LOCAL_SHARED_LIBRARIES:libcutils libutils libbinder  
  11.   
  12. LOCAL_MODULE :SharedBufferServer  
  13.   
  14. include $(BUILD_EXECUTABLE)  
        最后,我们再来看看client模块的实现。在external/ashmem/client目录下,只有一个源文件SharedBufferClient.cpp,它的内容如下所示:
  1. #define LOG_TAG "SharedBufferClient"  
  2.   
  3. #include <utils/Log.h>  
  4. #include <binder/MemoryBase.h>  
  5. #include <binder/IServiceManager.h>  
  6.   
  7. #include "../common/ISharedBuffer.h"  
  8.   
  9. int main()  
  10. {  
  11.         sp<IBinder> binder = defaultServiceManager()->getService(String16(SHARED_BUFFER_SERVICE));  
  12.         if(binder == NULL)  
  13.         {  
  14.                 printf("Failed to get service: %s.\n", SHARED_BUFFER_SERVICE);  
  15.                 return -1;  
  16.         }  
  17.   
  18.         sp<ISharedBuffer> service = ISharedBuffer::asInterface(binder);  
  19.         if(service == NULL)  
  20.         {  
  21.                 return -2;  
  22.         }  
  23.   
  24.         sp<IMemory> buffer = service->getBuffer();  
  25.         if(buffer == NULL)  
  26.         {  
  27.                 return -3;  
  28.         }  
  29.   
  30.         int32_t* data = (int32_t*)buffer->pointer();  
  31.         if(data == NULL)  
  32.         {  
  33.                 return -4;  
  34.         }  
  35.   
  36.         printf("The value of the shared buffer is %d.\n", *data);  
  37.   
  38.         *data = *data + 1;  
  39.   
  40.         printf("Add value 1 to the shared buffer.\n");  
  41.   
  42.         return 0;  
  43. }  
        在这个文件中,主要就是定义了Client端应用程序的入口函数main,在这个main函数里面,首先通过Service Manager接口获得前面所实现的匿名共享内存服务SharedBufferService的远程接口service,然后通过这个远程接口的getBuffer成员函数获得由Server端提供的一块匿名共享内存接口buffer,最后通过这个匿名共享内存接口获得这个匿名共享内存的基地址data。有了这个匿名共享内存的地址data之后,我们就可以对它进行读写了,先是把这个匿名共享内存当作是一个整型变量地址进行访问,并输出它的值的大小,然后对这个整量变量进行加1的操作,并写回到原来的共享内存空间中去。这样,当Server端应用程序运行之后,第一次运行这个Client端应用程序时,输出的值为0,第二次运行这个个Client端应用程序时,输出的值为1,第三次运行这个个Client端应用程序时,输出的值为3......依次类推,后面我们将在模拟器中对这个分析进行验证,如果验证成功的话,就说明这个匿名共享内存成功地在Server端和Client端实现共享了。
 




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966923,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
Linux 测试技术 语音技术
【车载Android】模拟Android系统的高负载环境
本文介绍如何将Linux压力测试工具Stress移植到Android系统,用于模拟高负载环境下的CPU、内存、IO和磁盘压力,帮助开发者优化车载Android应用在多任务并发时的性能问题,提升系统稳定性与用户体验。
206 6
|
2月前
|
Java 数据库 Android开发
基于Android的电子记账本系统
本项目研究开发一款基于Java与Android平台的开源电子记账系统,采用SQLite数据库和Gradle工具,实现高效、安全、便捷的个人财务管理,顺应数字化转型趋势。
|
4月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
175 26
|
9月前
|
存储 程序员 编译器
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
|
5月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
96 1
|
7月前
|
安全 搜索推荐 Android开发
Android系统SELinux安全机制详解
如此看来,SELinux对于大家来说,就像那位不眠不休,严阵以待的港口管理员,守护我们安卓系统的平安,维护这片海港的和谐生态。SELinux就这样,默默无闻,却卫士如山,给予Android系统一份厚重的安全保障。
245 18
|
11月前
|
存储 缓存 编译器
【硬核】C++11并发:内存模型和原子类型
本文从C++11并发编程中的关键概念——内存模型与原子类型入手,结合详尽的代码示例,抽丝剥茧地介绍了如何实现无锁化并发的性能优化。
471 68
|
8月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
9月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
432 0
|
10月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。

热门文章

最新文章