Android匿名共享内存使用简介

最近在优化打印机的打印速度,由于当前的实现存在许多内存拷贝的操作,于是希望借助于android匿名共享内存减少拷贝的次数,达到优化的目的。因为以前并未使用过Ashmem,仅以此篇记录下应用流程。

113245_EFwP_3750358.png

首先明确一点,共享内存一般应用在跨进程之间,原型如上图,fd为此块共享内存的文件描述符,Client和Server端通过文件描述符fd来操作共享内存

Client端实现步骤:

1.使用ashmem_create_region()接口创建一个长度为length的共享内存,并返回此内存块的文件描述赋

	data.fd = ashmem_create_region(NULL,length);
	if(data.fd < 0)
            LOGE(TAG,"Creating code cache, ashmem_create_region "
                                "failed with error '%s'", strerror(errno));

2.将此块共享内存以可读可写的方式映射到用户空间,并对此块内存写入数据

	data.data = (char *)mmap(NULL, data.length,
                                    PROT_READ | PROT_WRITE,
                                MAP_SHARED, data.fd, 0);
	if(data.data != MAP_FAILED){
		LOGE(TAG,"mmap sharemem success....");
		memcpy(data.data,gucDotBuffer,length);
		}else{
		LOGE(TAG,"mmap sharemem failed....'%s'",strerror(errno));
		}

3.解映射并关闭文件描述符

munmap(data.data,length);
close(data.fd);

4.通过binder通信,将共享内存的文件描述符通过Parcel提供的writeFileDescriptor()接口传递到服务端

Parcel data;
data.writeFileDescriptor(ash_data.fd,true);

服务端实现流程:

5.首先通过Parcel接口readFileDescriptor()接口取到共享内存块的文件描述符

Parcel data;
fd = data.readFileDescriptor();

6.将共享内存块mmap到服务端进程空间,之后就可以操作这块内存了

data.data = (char *)mmap(NULL, data.length,
                         PROT_READ | PROT_WRITE,
                         MAP_SHARED, data.fd, 0);
if(data.data != MAP_FAILED){
	LOGE(TAG,"mmap sharemem success....");
}else{
	LOGE(TAG,"mmap sharemem failed....'%s'",strerror(errno));
}

7.同理,使用完后需要解映射以及关闭文件描述符,防止内存泄漏

munmap(data.data,data.length);
close(data.fd);

 

注:补充一下,有一点比较有趣的地方是,Client和Server端的文件描述符fd的值打印出来你会发现两者是不一样的,这是因为,每个进程在进程表中都维护着自身的文件描述符表,binder驱动在传递fd的时候,调用了dup()函数对client端的文件描述符拷贝了一份副本给到Server端,两者值不同,但均指向同一个文件。

注2:每调用多一次dup(),返回值就会多加1

注3:需要依赖的头文件

#include <cutils/ashmem.h>
#include <sys/mman.h>

 

转载于:https://my.oschina.net/u/3750358/blog/1815998

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值