【发布时间】:2013-04-12 13:38:38
【问题描述】:
我已经在 Linux 中编写了一个简单的共享内存 C 程序。
如何在 Android 中使用共享内存(或者我应该称之为“ashmem?”)?
我希望你能给我一个分步指南。
【问题讨论】:
标签: android c linux shared-memory
我已经在 Linux 中编写了一个简单的共享内存 C 程序。
如何在 Android 中使用共享内存(或者我应该称之为“ashmem?”)?
我希望你能给我一个分步指南。
【问题讨论】:
标签: android c linux shared-memory
这对我有用:
1) 打开一个 MemoryFile 对象:mFile;
2) 创建服务以使用 mmap 将其映射到 ashem;
3) 使用 ParcelFileDescriptor pfd 将本机文件描述符 (fd) 返回到绑定到您的服务的客户端;
4) 为接受 fd 并使用 mmap 映射到灰烬的客户端创建 JNI;
5) 使用这个 fd 创建 InputStream,现在客户端可以使用 InputStream 对象读/写相同的内存区域。
这个link 展示了如何将 MemoryFile 映射到 ashem。这个link 展示了如何通过 AIDL 和 ParcelFileDescriptor 将本机文件描述符 (fd) 发送到客户端。
在服务器端,您需要创建:
1) 通过 ParcelFileDescriptor 将 native fd 传递给客户端的 service & AIDL;
2) 服务端执行映射的 JNI。
在客户端: 1)方法绑定到服务,然后调用服务获取原生fd; 2) 一个将 fd 映射到 ashem 的 JNI。
然后服务和客户端可以读取/写入映射的内存区域。
【讨论】:
一个进程通过以下步骤创建一个新的 ashmem 区域:
(1) 打开设备文件“/dev/ashmem”并获取文件描述符。 (2) 调用ASHMEM_SET_NAME ioctl 设置ashmem 名称。它似乎是虚拟设备文件,因此如果将其命名为“my_mem”,文件名将更改为“/dev/ashmem/my_mem”。 (3) 调用 ASHMEM_SET_SIZE ioctl 设置 ashmem 大小,以字节为单位。
cutils 库有一个函数“ashmem_create_region”,它将这些步骤封装到一个函数调用中:
int fd = ashmem_create_region("my_mem", PAGE_SIZE * 20);
文件描述符可以与其他进程共享。 Android 提供了一种特殊的方式来在表亲进程之间共享文件描述符,使用另一个名为“binder”的服务。然后每个进程对文件进行映射:
char *map = mmap(NULL, PAGE_SIZE * 20, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0);
而且,瞧!即时共享内存。
【讨论】:
在 Android 中使用 binder IPC。我认为绑定器使用所有进程共享的内核内存来进行进程间通信。
【讨论】:
ashmem 是您的最佳选择。
好吧,如果您想使用共享内存 API,这里有一个解决方案 https://github.com/pelya/android-shmem
就像魔术一样,它完美地运作。您可以使用 shmget()、shmat() 和 shmdt() API 无缝地在独立进程中使用 android 中的共享内存。试一试。
【讨论】: