android共享内存 c接口,Android 匿名共享内存 Ashmem(c 库接口)

Android 匿名共享内存 Ashmem(c 库接口)

Ashmem

Android 系统的匿名共享内存 Ashmem 驱动程序利用了 Linux 的共享内存子系统导出的接口来实现.

在 Android 系统中, 匿名共享内存也是进程间通信方式的一种.

相比于 malloc 和 anonymous/named mmap 等传统的内存分配机制, Ashmem 的优势是通过内核驱动提供了辅助内核的内存回收算法机制 (pin/unpin).

内存回收算法机制就是当你使用 Ashmem 分配了一块内存, 但是其中某些部分却不会被使用时, 那么就可以将这块内存 unpin 掉.

unpin 后, 内核可以将它对应的物理页面回收, 以作他用. 你也不用担心进程无法对 unpin 掉的内存进行再次访问, 因为回收后的内存还可以再次被获得 (通过缺页 handler), 因为 unpin 操作并不会改变已经 mmap 的地址空间.

Android 匿名共享内存接口

源码是最好的老师, 废话不多说, 直接看代码.

源码路径: system/core/libcutils/ashmem-dev.c

Android 源码中, ashmem 的实现:

打开共享内存:/*

* ashmem_create_region - creates a new ashmem region and returns the file

* descriptor, or <0 on error

*

* `name' is an optional label to give the region (visible in /proc/pid/maps)

* `size' is the size of the region, in page-aligned bytes

*/

intashmem_create_region(constchar*name,size_tsize)

{

intret,save_errno;

intfd=__ashmem_open();

if(fd<0){

returnfd;

}

if(name){

charbuf[ASHMEM_NAME_LEN]={0};

strlcpy(buf,name,sizeof(buf));

ret=TEMP_FAILURE_RETRY(ioctl(fd,ASHMEM_SET_NAME,buf));

if(ret<0){

gotoerror;

}

}

ret=TEMP_FAILURE_RETRY(ioctl(fd,ASHMEM_SET_SIZE,size));

if(ret<0){

gotoerror;

}

returnfd;

error:

save_errno=errno;

close(fd);

errno=save_errno;

returnret;

}

在函数中调用驱动接口:

__ashmem_open

__ashmem_open 函数的实现如下:/* logistics of getting file descriptor for ashmem */

staticint__ashmem_open_locked()

{

intret;

structstat st;

intfd=TEMP_FAILURE_RETRY(open(ASHMEM_DEVICE,O_RDWR));

if(fd<0){

returnfd;

}

ret=TEMP_FAILURE_RETRY(fstat(fd,&st));

if(ret<0){

intsave_errno=errno;

close(fd);

errno=save_errno;

returnret;

}

if(!S_ISCHR(st.st_mode)||!st.st_rdev){

close(fd);

errno=ENOTTY;

return-1;

}

__ashmem_rdev=st.st_rdev;

returnfd;

}

staticint__ashmem_open()

{

intfd;

pthread_mutex_lock(&__ashmem_lock);

fd=__ashmem_open_locked();

pthread_mutex_unlock(&__ashmem_lock);

returnfd;

}

可见函数最后是通过 open 去操作 ashmem 驱动文件.

返回为一个文件描述符.intashmem_valid(intfd)

{

return__ashmem_is_ashmem(fd,0)>=0;

}

除此之外, 源码中还提供了几个接口函数:

1. 锁定匿名共享内存块intashmem_pin_region(intfd,size_toffset,size_tlen)

{

structashmem_pin pin={offset,len};

intret=__ashmem_is_ashmem(fd,1);

if(ret<0){

returnret;

}

returnTEMP_FAILURE_RETRY(ioctl(fd,ASHMEM_PIN,&pin));

}

2. 解锁匿名共享内存块intashmem_unpin_region(intfd,size_toffset,size_tlen)

{

structashmem_pin pin={offset,len};

intret=__ashmem_is_ashmem(fd,1);

if(ret<0){

returnret;

}

returnTEMP_FAILURE_RETRY(ioctl(fd,ASHMEM_UNPIN,&pin));

}

3. 获取大小intashmem_get_size_region(intfd)

{

intret=__ashmem_is_ashmem(fd,1);

if(ret<0){

returnret;

}

returnTEMP_FAILURE_RETRY(ioctl(fd,ASHMEM_GET_SIZE,NULL));

}

因为是文件描述符, 所以关闭直接采用 close.

close(fd)

使用例子

创建共享内存fd=ashmem_create_region(NULL,length);

if(fd<0)

printf("Creating code cache, ashmem_create_region error.");

将共享内存映射到用户空间data=(char*)mmap(NULL,data.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(data!=MAP_FAILED){

printf("mmap sharemem success....");

memcpy(data.data,gucDotBuffer,length);

}else{

printf("mmap sharemem failed....'%s'",strerror(errno));

}

关闭映射并关闭共享内存文件munmap(data,length);

close(fd);

来源: http://www.jianshu.com/p/41c4b1bf4873

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值