aboutsummaryrefslogtreecommitdiff
path: root/zh-cn/devices/architecture/hidl/fmq.html
diff options
context:
space:
mode:
Diffstat (limited to 'zh-cn/devices/architecture/hidl/fmq.html')
-rw-r--r--zh-cn/devices/architecture/hidl/fmq.html26
1 files changed, 16 insertions, 10 deletions
diff --git a/zh-cn/devices/architecture/hidl/fmq.html b/zh-cn/devices/architecture/hidl/fmq.html
index c5fb1fd7..05372de6 100644
--- a/zh-cn/devices/architecture/hidl/fmq.html
+++ b/zh-cn/devices/architecture/hidl/fmq.html
@@ -27,7 +27,7 @@
<p class="caution">仅 C++ 支持快速消息队列。</p>
<h2 id="flavors">MessageQueue 类型</h2>
-<p>Android 支持两种队列类型:</p>
+<p>Android 支持两种队列类型(称为“风格”<em></em>):</p>
<ul>
<li>未同步队列:可以溢出,并且可以有多个读取器;每个读取器都必须及时读取数据,否则数据将会丢失。<em></em>
</li><li>已同步队列:不能溢出,并且只能有一个读取器。<em></em></li>
@@ -83,13 +83,13 @@ configureEventFlagWord)</code> 初始化程序负责创建并初始化支持消
</ul>
<h3 id="second-object">创建第二个 MessageQueue 对象</h3>
-<p>使用从消息队列的第一侧获取的 <code>MQDescriptor</code> 对象创建消息队列的第二侧。通过 HIDL RPC 调用将 <code>MQDescriptor</code> 对象发送到将容纳消息队列末端的进程。<code>MQDescriptor</code> 包含该队列的相关信息:</p>
+<p>使用从消息队列的第一侧获取的 <code>MQDescriptor</code> 对象创建消息队列的第二侧。通过 HIDL RPC 调用将 <code>MQDescriptor</code> 对象发送到将容纳消息队列末端的进程。<code>MQDescriptor</code> 包含该队列的相关信息,其中包括:</p>
<ul>
<li>用于映射缓冲区和写入指针的信息。</li>
-<li>(如果队列已同步)用于映射读取指针的信息。</li>
-<li>(如果队列是阻塞队列)用于映射事件标记字词的信息。</li>
-<li>对象类型被制作成一个具有 HIDL 定义的队列元素类型和风格(已同步或未同步)的模板。</li>
+<li>用于映射读取指针的信息(如果队列已同步)。</li>
+<li>用于映射事件标记字词的信息(如果队列是阻塞队列)。</li>
+<li>对象类型 (<code>&lt;T, flavor&gt;</code>),其中包含 <a href="/devices/architecture/hidl-cpp/types.html">HIDL 定义的队列元素类型</a>和队列风格(已同步或未同步)。</li>
</ul>
<p><code>MQDescriptor</code> 对象可用于构建 <code>MessageQueue</code> 对象:</p>
@@ -98,13 +98,19 @@ configureEventFlagWord)</code> 初始化程序负责创建并初始化支持消
MessageQueue&lt;T, flavor&gt;::MessageQueue(const MQDescriptor&lt;T, flavor&gt;&amp; Desc, bool resetPointers)
</pre>
-<p><code>resetPointers</code> 参数表示是否在创建此 <code>MessageQueue</code> 对象时将读取和写入位置重置为 0。在未同步队列中,读取位置(在未同步队列中,是每个 <code>MessageQueue</code> 对象的本地位置)在此对象创建过程中始终设为 0。通常,<code>MQDescriptor</code> 是在创建第一个消息队列对象过程中初始化的。要对共享内存进行额外的控制,您可以手动设置 <code>MQDescriptor</code>(<code>MQDescriptor</code> 是在 <a href="https://android.googlesource.com/platform/system/libhidl/+/master/base/include/hidl/MQDescriptor.h" class="external"><code>system/libhidl/base/include/hidl/MQDescriptor.h</code></a> 中定义的),然后按照本部分所述创建每个 <code>MessageQueue</code> 对象。
+<p><code>resetPointers</code> 参数表示是否在创建此 <code>MessageQueue</code> 对象时将读取和写入位置重置为 0。在未同步队列中,读取位置(在未同步队列中,是每个 <code>MessageQueue</code> 对象的本地位置)在此对象创建过程中始终设为 0。通常,<code>MQDescriptor</code> 是在创建第一个消息队列对象过程中初始化的。要对共享内存进行额外的控制,您可以手动设置 <code>MQDescriptor</code>(<code>MQDescriptor</code> 是在 <a href="https://android.googlesource.com/platform/system/libhidl/+/master/base/include/hidl/MQDescriptor.h" class="external"><code>system/libhidl/base/include/hidl/MQDescriptor.h</code></a> 中定义的),然后按照本部分所述内容创建每个 <code>MessageQueue</code> 对象。
</p>
<h3 id="blocking">阻塞队列和事件标记</h3>
<p>默认情况下,队列不支持阻塞读取/写入。有两种类型的阻塞读取/写入调用:</p>
<ul>
-<li>短格式:有三个参数(数据指针、项数、超时)。<em></em>支持阻塞针对单个队列的各个读取/写入操作。在使用这种格式时,队列将在内部处理事件标记和位掩码,并且第一个消息队列对象必须初始化为第二个参数为 <code>true</code>。</li>
+<li>短格式:有三个参数(数据指针、项数、超时)。<em></em>支持阻塞针对单个队列的各个读取/写入操作。在使用这种格式时,队列将在内部处理事件标记和位掩码,并且<a href="#first-object">第一个消息队列对象</a>必须初始化为第二个参数为 <code>true</code>。例如:<pre>
+// For an unsynchronized FMQ that supports blocking
+mFmqUnsynchronizedBlocking =
+ new (std::nothrow) MessageQueue&lt;uint16_t, kUnsynchronizedWrite&gt;
+ (kNumElementsInQueue, true /* enable blocking operations */);
+<pre>
+</pre></pre></li>
<li>长格式:有六个参数(包括事件标记和位掩码)。<em></em>支持在多个队列之间使用共享 <code>EventFlag</code> 对象,并允许指定要使用的通知位掩码。在这种情况下,必须为每个读取和写入调用提供事件标记和位掩码。</li>
</ul>
@@ -166,11 +172,11 @@ bool commitRead(size_t nMessages);
<p><code>readBlocking()</code> 会等待 <code>writeNotification</code> 位;如果该参数为 0,则调用一定会失败。如果 <code>readNotification</code> 值为 0,则调用不会失败,但成功的读取操作将不会设置任何通知位。在已同步队列中,这意味着相应的 <code>writeBlocking()</code> 调用一定不会唤醒,除非已在其他位置对相应的位进行设置。在未同步队列中,<code>writeBlocking()</code> 将不会等待(它应仍用于设置写入通知位),而且对于读取操作来说,不适合设置任何通知位。同样,如果 <code>readNotification</code> 为 0,<code>writeblocking()</code> 将会失败,并且成功的写入操作会设置指定的 <code>writeNotification</code> 位。</p>
-<p>要一次等待多个队列,请使用 <code>EventFlag</code> 对象的 <code>wait()</code> 方法来等待通知的位掩码。<code>wait()</code> 方法会返回一个状态字词以及导致系统设置唤醒的位。然后,用户可以使用该信息检查相应的队列,看看是否有足够的空间或数据来完成所需的写入或读取操作,并执行非阻塞 <code>read()</code>/<code>write()</code>。接下来,如果要收到操作后通知,可以再次调用 <code>EventFlag</code> 的 <code>wake()</code> 方法。有关 <code>EventFlag</code> 抽象的定义,请参阅 <a href="https://android.googlesource.com/platform/system/libfmq/+/master/include/fmq/EventFlag.h" class="external"><code>system/libfmq/include/fmq/EventFlag.h</code></a>。
+<p>要一次等待多个队列,请使用 <code>EventFlag</code> 对象的 <code>wait()</code> 方法来等待通知的位掩码。<code>wait()</code> 方法会返回一个状态字词以及导致系统设置唤醒的位。然后,该信息可用于验证相应的队列是否有足够的控件或数据来完成所需的写入/读取操作,并执行非阻塞 <code>write()</code>/<code>read()</code>。要获取操作后通知,请再次调用 <code>EventFlag</code> 的 <code>wake()</code> 方法。有关 <code>EventFlag</code> 抽象的定义,请参阅 <a href="https://android.googlesource.com/platform/system/libfmq/+/master/include/fmq/EventFlag.h" class="external"><code>system/libfmq/include/fmq/EventFlag.h</code></a>。
</p>
<h2 id="zero">零复制操作</h2>
-<p><code>read</code>/<code>write</code>/<code>readBlocking</code>/<code>writeBlocking()</code> API 会将指向输入/输出缓冲区的指针作为参数,并在内部使用 <code>memcpy()</code> 调用,以便在相应缓冲区和 FMQ 环形缓冲区之间复制数据。为了提高性能,Android O 包含一组 API,这些 API 可提供对环形缓冲区的直接指针访问,这样便无需使用 <code>memcpy</code> 调用。</p>
+<p><code>read</code>/<code>write</code>/<code>readBlocking</code>/<code>writeBlocking()</code> API 会将指向输入/输出缓冲区的指针作为参数,并在内部使用 <code>memcpy()</code> 调用,以便在相应缓冲区和 FMQ 环形缓冲区之间复制数据。为了提高性能,Android 8.0 及更高版本包含一组 API,这些 API 可提供对环形缓冲区的直接指针访问,这样便无需使用 <code>memcpy</code> 调用。</p>
<p>使用以下公共 API 执行零复制 FMQ 操作:</p>
@@ -185,7 +191,7 @@ bool commitRead(size_t nMessages);
<ul>
<li><code>beginWrite</code> 方法负责提供用于访问 FMQ 环形缓冲区的基址指针。在数据写入之后,使用 <code>commitWrite()</code> 提交数据。<code>beginRead</code>/<code>commitRead</code> 方法的运作方式与之相同。</li>
<li><code>beginRead</code>/<code>Write</code> 方法会将要读取/写入的消息条数视为输入,并会返回一个布尔值来指示是否可以执行读取/写入操作。如果可以执行读取或写入操作,则 <code>memTx</code> 结构体中会填入基址指针,这些指针可用于对环形缓冲区共享内存进行直接指针访问。</li>
-<li><code>MemRegion</code> 结构体包含有关内存块的详细信息,其中包括基址指针(内存块的基址)和以 <code>T</code> 表示的长度(以 HIDL 定义的消息队列类型表示的内存块长度)。</li>
+<li><code>MemRegion</code> 结构体包含有关内存块的详细信息,其中包括基础指针(内存块的基址)和以 <code>T</code> 表示的长度(以 HIDL 定义的消息队列类型表示的内存块长度)。</li>
<li><code>MemTransaction</code> 结构体包含两个 <code>MemRegion</code> 结构体(<code>first</code> 和 <code>second</code>),因为对环形缓冲区执行读取或写入操作时可能需要绕回到队列开头。这意味着,要对 FMQ 环形缓冲区执行数据读取/写入操作,需要两个基址指针。</li>
</ul>