📄 async_queues.sgml
字号:
<refentry id="glib-Asynchronous-Queues"><refmeta><refentrytitle>Asynchronous Queues</refentrytitle><manvolnum>3</manvolnum><refmiscinfo>GLIB Library</refmiscinfo></refmeta><refnamediv><refname>Asynchronous Queues</refname><refpurpose>asynchronous communication between threads.</refpurpose></refnamediv><refsynopsisdiv><title>Synopsis</title><synopsis>#include <glib.h>struct <link linkend="GAsyncQueue">GAsyncQueue</link>;<link linkend="GAsyncQueue">GAsyncQueue</link>* <link linkend="g-async-queue-new">g_async_queue_new</link> (void);void <link linkend="g-async-queue-ref">g_async_queue_ref</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-unref">g_async_queue_unref</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-push">g_async_queue_push</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="gpointer">gpointer</link> data);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-pop">g_async_queue_pop</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-try-pop">g_async_queue_try_pop</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-timed-pop">g_async_queue_timed_pop</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="GTimeVal">GTimeVal</link> *end_time);<link linkend="gint">gint</link> <link linkend="g-async-queue-length">g_async_queue_length</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-lock">g_async_queue_lock</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-unlock">g_async_queue_unlock</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-ref-unlocked">g_async_queue_ref_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-unref-and-unlock">g_async_queue_unref_and_unlock</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);void <link linkend="g-async-queue-push-unlocked">g_async_queue_push_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="gpointer">gpointer</link> data);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-pop-unlocked">g_async_queue_pop_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-try-pop-unlocked">g_async_queue_try_pop_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);<link linkend="gpointer">gpointer</link> <link linkend="g-async-queue-timed-pop-unlocked">g_async_queue_timed_pop_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="GTimeVal">GTimeVal</link> *end_time);<link linkend="gint">gint</link> <link linkend="g-async-queue-length-unlocked">g_async_queue_length_unlocked</link> (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</synopsis></refsynopsisdiv><refsect1><title>Description</title><para>Often you need to communicate between different threads. In generalit's safer not to do this by shared memory, but by explicit messagepassing. These messages only make sense asynchronously formulti-threaded applications though, as a synchronous operation could aswell be done in the same thread.</para><para>Asynchronous queues are an exception from most other GLib datastructures, as they can be used simultaneously from multiple threadswithout explicit locking and they bring their own builtin referencecounting. This is because the nature of an asynchronous queue is thatit will always be used by at least 2 concurrent threads.</para><para>For using an asynchronous queue you first have to create one with<link linkend="g-async-queue-new">g_async_queue_new</link>(). A newly-created queue will get the referencecount 1. Whenever another thread is creating a new reference of (thatis, pointer to) the queue, it has to increase the reference count(using <link linkend="g-async-queue-ref">g_async_queue_ref</link>()). Also, before removing this reference, thereference count has to be decreased (using<link linkend="g-async-queue-unref">g_async_queue_unref</link>()). After that the queue might no longer exist soyou must not access it after that point.</para><para>A thread, which wants to send a message to that queue simply calls<link linkend="g-async-queue-push">g_async_queue_push</link>() to push the message to the queue.</para><para>A thread, which is expecting messages from an asynchronous queuesimply calls <link linkend="g-async-queue-pop">g_async_queue_pop</link>() for that queue. If no message isavailable in the queue at that point, the thread is now put to sleepuntil a message arrives. The message will be removed from the queueand returned. The functions <link linkend="g-async-queue-try-pop">g_async_queue_try_pop</link>() and<link linkend="g-async-queue-timed-pop">g_async_queue_timed_pop</link>() can be used to only check for the presenceof messages or to only wait a certain time for messages respectively.</para><para>For almost every function there exist two variants, one that locks thequeue and one that doesn't. That way you can hold the queue lock(acquire it with <link linkend="g-async-queue-lock">g_async_queue_lock</link>() and release it with<link linkend="g-async-queue-unlock">g_async_queue_unlock</link>()) over multiple queue accessinginstructions. This can be necessary to ensure the integrity of thequeue, but should only be used when really necessary, as it can makeyour life harder if used unwisely. Normally you should only use thelocking function variants (those without the suffix _unlocked)</para></refsect1><refsect1><title>Details</title><refsect2><title><anchor id="GAsyncQueue">struct GAsyncQueue</title><programlisting>struct GAsyncQueue;</programlisting><para>The <link linkend="GAsyncQueue">GAsyncQueue</link> struct is an opaque data structure, which representsan asynchronous queue. It should only be accessed through the<function>g_async_queue_*</function> functions.</para></refsect2><refsect2><title><anchor id="g-async-queue-new">g_async_queue_new ()</title><programlisting><link linkend="GAsyncQueue">GAsyncQueue</link>* g_async_queue_new (void);</programlisting><para>Creates a new asynchronous queue with the initial reference count of 1.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><emphasis>Returns</emphasis> :</entry><entry> the new <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-ref">g_async_queue_ref ()</title><programlisting>void g_async_queue_ref (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting><para>Increases the reference count of the asynchronous <parameter>queue</parameter> by 1.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><parameter>queue</parameter> :</entry><entry> a <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-unref">g_async_queue_unref ()</title><programlisting>void g_async_queue_unref (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting><para>Decreases the reference count of the asynchronous <parameter>queue</parameter> by 1. Ifthe reference count went to 0, the <parameter>queue</parameter> will be destroyed and thememory allocated will be freed. So you are not allowed to use the<parameter>queue</parameter> afterwards, as it might have disappeared.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><parameter>queue</parameter> :</entry><entry> a <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-push">g_async_queue_push ()</title><programlisting>void g_async_queue_push (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="gpointer">gpointer</link> data);</programlisting><para>Pushes the <parameter>data</parameter> into the <parameter>queue</parameter>. <parameter>data</parameter> must not be <literal>NULL</literal>.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><parameter>queue</parameter> :</entry><entry> a <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row><row><entry align="right"><parameter>data</parameter> :</entry><entry> <parameter>data</parameter> to push into the <parameter>queue</parameter>.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-pop">g_async_queue_pop ()</title><programlisting><link linkend="gpointer">gpointer</link> g_async_queue_pop (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting><para>Pops data from the <parameter>queue</parameter>. This function blocks until data becomeavailable.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><parameter>queue</parameter> :</entry><entry> a <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row><row><entry align="right"><emphasis>Returns</emphasis> :</entry><entry> data from the queue.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-try-pop">g_async_queue_try_pop ()</title><programlisting><link linkend="gpointer">gpointer</link> g_async_queue_try_pop (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue);</programlisting><para>Tries to pop data from the <parameter>queue</parameter>. If no data is available, <literal>NULL</literal> isreturned.</para><informaltable pgwide="1" frame="none" role="params"><tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*"><tbody><row><entry align="right"><parameter>queue</parameter> :</entry><entry> a <link linkend="GAsyncQueue">GAsyncQueue</link>.</entry></row><row><entry align="right"><emphasis>Returns</emphasis> :</entry><entry> data from the queue or <literal>NULL</literal>, when no data isavailable immediately.</entry></row></tbody></tgroup></informaltable></refsect2><refsect2><title><anchor id="g-async-queue-timed-pop">g_async_queue_timed_pop ()</title><programlisting><link linkend="gpointer">gpointer</link> g_async_queue_timed_pop (<link linkend="GAsyncQueue">GAsyncQueue</link> *queue, <link linkend="GTimeVal">GTimeVal</link> *end_time);</programlisting><para>Pops data from the <parameter>queue</parameter>. If no data is received before <parameter>end_time</parameter>,<literal>NULL</literal> is returned.</para><para>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -