Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
写信给ashmem/为什么android会免费提供ashmem?_Android_Android Ndk_Shared Memory_Ashmem - Fatal编程技术网

写信给ashmem/为什么android会免费提供ashmem?

写信给ashmem/为什么android会免费提供ashmem?,android,android-ndk,shared-memory,ashmem,Android,Android Ndk,Shared Memory,Ashmem,我想在两个(ndk-)进程之间共享数据。为此,我使用ashmem,并使用此工具。 一个进程连续读取(read\u mem),一个进程一次写入(write\u mem) 问题是读取过程没有获取写入程序的值 和 通过查看阅读器的地图,我发现android在ashmem\u create\u region之后删除了共享内存文件 阅读(mem.c) 书写 shell@mako:/data/local/tmp $ ./write_mem ashmem_create_region: 3 PID=29691

我想在两个(ndk-)进程之间共享数据。为此,我使用ashmem,并使用此工具。
一个进程连续读取(
read\u mem
),一个进程一次写入(
write\u mem

问题是读取过程没有获取写入程序的值

通过查看阅读器的地图,我发现android在
ashmem\u create\u region
之后删除了共享内存文件


阅读(mem.c) 书写

shell@mako:/data/local/tmp $ ./write_mem
ashmem_create_region: 3
PID=29691
A
Written 0x41
再次读取
VALUE=0x0
(按回车键)

观看读者的地图:

shell@mako:/ $ cat /proc/29655/maps | grep test_mem
b6ef5000-b6ef6000 rw-s 00000000 00:04 116213     /dev/ashmem/test_mem (deleted)
如您所见,
test\u mem
read\u mem
仍处于活动状态时被删除


其他资料 这两个文件都使用android
ndk build
命令编译为可执行文件
设备:LG Nexus 4(AOSP Lollypop)
我检查了它是否存在。

ashmem取自

ashmem,它不像Linux上的常规共享内存那样工作,这是有充分理由的

首先,让我们试着解释一下“(已删除)”部分,这是如何在内核中实现ashmem的实现细节。它真正的意思是在/dev/ashmem/目录中创建了一个文件条目,然后将其删除,但相应的i节点仍然存在,因为它至少有一个打开的文件描述符

实际上,您可以创建几个具有相同名称的ashmem区域,它们都将显示为“/dev/ashmem/(deleted)”,但它们中的每一个都将对应于不同的i节点,从而对应于不同的内存区域。如果您在/dev/ashmem/下查看,您会看到目录仍然是空的

这就是为什么ashmem区域的名称实际上只用于调试。无法按名称“打开”现有区域

当最后一个文件描述符关闭时,自动回收ashmem i节点和相应的内存。这很有用,因为这意味着如果进程因崩溃而死亡,那么内核将自动回收内存。常规SysV共享内存的情况并非如此(崩溃的进程只会泄漏内存!这在Android这样的嵌入式系统上是不可接受的)

您的测试程序创建了两个不同的ashmem区域,它们具有相同的名称,这就是为什么它们不能像您认为的那样工作。您需要的是:

1) 在其中一个过程中创建一个ashmem区域

2) 将新的文件描述符传递到从第一个进程到第二个进程的区域

一种方法是分叉第一个进程来创建第二个进程(这将自动复制文件描述符),但在Android下这通常不是一个好主意

更好的替代方法是使用sendmsg()和recvmsg()通过两个进程之间的Unix域套接字发送文件描述符。这通常很棘手,但作为一个示例,请查看以下源文件中为NDK编写的SendFd()和ReceiveFd()函数:


瞧,希望这有帮助

地图仍然存在,它只是在标签上显示“(已删除)”?我仍然能够读写缓冲区是的。但数据似乎不会被写入
msync
没有区别。但为什么输出中的FD相同?文件描述符编号是特定于进程的。默认情况下,一个命令行可执行文件将打开3个文件描述符(0=stdin/1=stdout/2=stderr),因此第一个open()调用可能返回3。抱歉,似乎疯狂的链接器源已被移动,这里有一个链接,指向同一源的上一次提交,其中包含有效的SendFd()和ReceiveFd()功能:@Digit您能指出创建ashmem区域时文件条目添加和后续删除的具体位置吗?尽管这里有一个错误,但它对内部进行了很好的描述,所以进行了升级。没有
/dev/ashmem/
文件夹,有一个
/dev/ashmem
设备文件,
/proc//maps
中有
/dev/ashmem/(已删除)
条目,它们只是名称。
130|shell@mako:/data/local/tmp $ ./read_mem
ashmem_create_region: 3
PID=29655
VALUE = 0x0
shell@mako:/data/local/tmp $ ./write_mem
ashmem_create_region: 3
PID=29691
A
Written 0x41
shell@mako:/ $ cat /proc/29655/maps | grep test_mem
b6ef5000-b6ef6000 rw-s 00000000 00:04 116213     /dev/ashmem/test_mem (deleted)