<refentry id="glib-Thread-Pools"> <refmeta> <refentrytitle>Thread Pools</refentrytitle> <manvolnum>3</manvolnum> <refmiscinfo>GLIB Library</refmiscinfo> </refmeta> <refnamediv> <refname>Thread Pools</refname><refpurpose>pools of threads to execute work concurrently.</refpurpose> </refnamediv> <refsynopsisdiv><title>Synopsis</title> <synopsis> #include <glib.h> struct <link linkend="GThreadPool">GThreadPool</link>; <link linkend="GThreadPool">GThreadPool</link>* <link linkend="g-thread-pool-new">g_thread_pool_new</link> (<link linkend="GFunc">GFunc</link> func, <link linkend="gpointer">gpointer</link> user_data, <link linkend="gint">gint</link> max_threads, <link linkend="gboolean">gboolean</link> exclusive, <link linkend="GError">GError</link> **error); <link linkend="void">void</link> <link linkend="g-thread-pool-push">g_thread_pool_push</link> (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gpointer">gpointer</link> data, <link linkend="GError">GError</link> **error); <link linkend="void">void</link> <link linkend="g-thread-pool-set-max-threads">g_thread_pool_set_max_threads</link> (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gint">gint</link> max_threads, <link linkend="GError">GError</link> **error); <link linkend="gint">gint</link> <link linkend="g-thread-pool-get-max-threads">g_thread_pool_get_max_threads</link> (<link linkend="GThreadPool">GThreadPool</link> *pool); <link linkend="guint">guint</link> <link linkend="g-thread-pool-get-num-threads">g_thread_pool_get_num_threads</link> (<link linkend="GThreadPool">GThreadPool</link> *pool); <link linkend="guint">guint</link> <link linkend="g-thread-pool-unprocessed">g_thread_pool_unprocessed</link> (<link linkend="GThreadPool">GThreadPool</link> *pool); <link linkend="void">void</link> <link linkend="g-thread-pool-free">g_thread_pool_free</link> (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gboolean">gboolean</link> immediate, <link linkend="gboolean">gboolean</link> wait); <link linkend="void">void</link> <link linkend="g-thread-pool-set-max-unused-threads">g_thread_pool_set_max_unused_threads</link> (<link linkend="gint">gint</link> max_threads); <link linkend="gint">gint</link> <link linkend="g-thread-pool-get-max-unused-threads">g_thread_pool_get_max_unused_threads</link> (void); <link linkend="guint">guint</link> <link linkend="g-thread-pool-get-num-unused-threads">g_thread_pool_get_num_unused_threads</link> (void); <link linkend="void">void</link> <link linkend="g-thread-pool-stop-unused-threads">g_thread_pool_stop_unused_threads</link> (void); </synopsis> </refsynopsisdiv> <refsect1> <title>Description</title> <para> Sometimes you wish to asyncronously fork out the execution of work and continue working in your own thread. If that will happen often, the overhead of starting and destroying a thread each time might be to high. In such cases reusing already started threads seems like a good idea. And it indeed is, but implementing this can be tedious and error-prone. </para> <para> Therefore GLib provides thread pools for your convenience. An added advantage is, that the threads can be shared between the different subsystems of your program, when they are using GLib. </para> <para> To create a new thread pool, you use <link linkend="g-thread-pool-new"><function>g_thread_pool_new()</function></link>. It is destroyed by <link linkend="g-thread-pool-free"><function>g_thread_pool_free()</function></link>. </para> <para> If you want to execute a certain task within a thread pool, you call <link linkend="g-thread-pool-push"><function>g_thread_pool_push()</function></link>. </para> <para> To get the current number of running threads you call <link linkend="g-thread-pool-get-num-threads"><function>g_thread_pool_get_num_threads()</function></link>. To get the number of still unprocessed tasks you call <link linkend="g-thread-pool-unprocessed"><function>g_thread_pool_unprocessed()</function></link>. To control the maximal number of threads for a thread pool, you use <link linkend="g-thread-pool-get-max-threads"><function>g_thread_pool_get_max_threads()</function></link> and <link linkend="g-thread-pool-set-max-threads"><function>g_thread_pool_set_max_threads()</function></link>. </para> <para> Finally you can control the number of unused threads, that are kept alive by GLib for future use. The current number can be fetched with <link linkend="g-thread-pool-get-num-unused-threads"><function>g_thread_pool_get_num_unused_threads()</function></link>. The maximal number can be controlled by <link linkend="g-thread-pool-get-max-unused-threads"><function>g_thread_pool_get_max_unused_threads()</function></link> and <link linkend="g-thread-pool-set-max-unused-threads"><function>g_thread_pool_set_max_unused_threads()</function></link>. All currently unused threads can be stopped by calling <link linkend="g-thread-pool-stop-unused-threads"><function>g_thread_pool_stop_unused_threads()</function></link>. </para> </refsect1> <refsect1> <title>Details</title> <refsect2> <title><anchor id="GThreadPool"/>struct GThreadPool</title> <indexterm><primary>GThreadPool</primary></indexterm><programlisting>struct GThreadPool { GFunc func; gpointer user_data; gboolean exclusive; }; </programlisting> <para> The <link linkend="GThreadPool"><type>GThreadPool</type></link> struct represents a thread pool. It has six public read-only members, but the underlying struct is bigger, so you must not copy this struct. </para><variablelist role="struct"> <varlistentry> <term><link linkend="GFunc">GFunc</link> <structfield>func</structfield></term> <listitem><simpara>the function to execute in the threads of this pool </simpara></listitem> </varlistentry> <varlistentry> <term><link linkend="gpointer">gpointer</link> <structfield>user_data</structfield></term> <listitem><simpara>the user data for the threads of this pool </simpara></listitem> </varlistentry> <varlistentry> <term><link linkend="gboolean">gboolean</link> <structfield>exclusive</structfield></term> <listitem><simpara>are all threads exclusive to this pool </simpara></listitem> </varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-new"/>g_thread_pool_new ()</title> <indexterm><primary>g_thread_pool_new</primary></indexterm><programlisting><link linkend="GThreadPool">GThreadPool</link>* g_thread_pool_new (<link linkend="GFunc">GFunc</link> func, <link linkend="gpointer">gpointer</link> user_data, <link linkend="gint">gint</link> max_threads, <link linkend="gboolean">gboolean</link> exclusive, <link linkend="GError">GError</link> **error);</programlisting> <para> This function creates a new thread pool. </para> <para> Whenever you call <link linkend="g-thread-pool-push"><function>g_thread_pool_push()</function></link>, either a new thread is created or an unused one is reused. At most <parameter>max_threads</parameter> threads are running concurrently for this thread pool. <parameter>max_threads</parameter> = -1 allows unlimited threads to be created for this thread pool. The newly created or reused thread now executes the function <parameter>func</parameter> with the two arguments. The first one is the parameter to <link linkend="g-thread-pool-push"><function>g_thread_pool_push()</function></link> and the second one is <parameter>user_data</parameter>. </para> <para> The parameter <parameter>exclusive</parameter> determines, whether the thread pool owns all threads exclusive or whether the threads are shared globally. If <parameter>exclusive</parameter> is <literal>TRUE</literal>, <parameter>max_threads</parameter> threads are started immediately and they will run exclusively for this thread pool until it is destroyed by <link linkend="g-thread-pool-free"><function>g_thread_pool_free()</function></link>. If <parameter>exclusive</parameter> is <literal>FALSE</literal>, threads are created, when needed and shared between all non-exclusive thread pools. This implies that <parameter>max_threads</parameter> may not be -1 for exclusive thread pools. </para> <para> <parameter>error</parameter> can be <literal>NULL</literal> to ignore errors, or non-<literal>NULL</literal> to report errors. An error can only occur when <parameter>exclusive</parameter> is set to <literal>TRUE</literal> and not all <parameter>max_threads</parameter> threads could be created.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>func</parameter> :</term> <listitem><simpara> a function to execute in the threads of the new thread pool </simpara></listitem></varlistentry> <varlistentry><term><parameter>user_data</parameter> :</term> <listitem><simpara> user data that is handed over to <parameter>func</parameter> every time it is called </simpara></listitem></varlistentry> <varlistentry><term><parameter>max_threads</parameter> :</term> <listitem><simpara> the maximal number of threads to execute concurrently in the new thread pool, -1 means no limit </simpara></listitem></varlistentry> <varlistentry><term><parameter>exclusive</parameter> :</term> <listitem><simpara> should this thread pool be exclusive? </simpara></listitem></varlistentry> <varlistentry><term><parameter>error</parameter> :</term> <listitem><simpara> return location for error </simpara></listitem></varlistentry> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the new <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-push"/>g_thread_pool_push ()</title> <indexterm><primary>g_thread_pool_push</primary></indexterm><programlisting><link linkend="void">void</link> g_thread_pool_push (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gpointer">gpointer</link> data, <link linkend="GError">GError</link> **error);</programlisting> <para> Inserts <parameter>data</parameter> into the list of tasks to be executed by <parameter>pool</parameter>. When the number of currently running threads is lower than the maximal allowed number of threads, a new thread is started (or reused) with the properties given to <link linkend="g-thread-pool-new"><function>g_thread_pool_new()</function></link>. Otherwise <parameter>data</parameter> stays in the queue until a thread in this pool finishes its previous task and processes <parameter>data</parameter>. </para> <para> <parameter>error</parameter> can be <literal>NULL</literal> to ignore errors, or non-<literal>NULL</literal> to report errors. An error can only occur when a new thread couldn't be created. In that case <parameter>data</parameter> is simply appended to the queue of work to do.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><parameter>data</parameter> :</term> <listitem><simpara> a new task for <parameter>pool</parameter> </simpara></listitem></varlistentry> <varlistentry><term><parameter>error</parameter> :</term> <listitem><simpara> return location for error </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-set-max-threads"/>g_thread_pool_set_max_threads ()</title> <indexterm><primary>g_thread_pool_set_max_threads</primary></indexterm><programlisting><link linkend="void">void</link> g_thread_pool_set_max_threads (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gint">gint</link> max_threads, <link linkend="GError">GError</link> **error);</programlisting> <para> Sets the maximal allowed number of threads for <parameter>pool</parameter>. A value of -1 means, that the maximal number of threads is unlimited. </para> <para> Setting <parameter>max_threads</parameter> to 0 means stopping all work for <parameter>pool</parameter>. It is effectively frozen until <parameter>max_threads</parameter> is set to a non-zero value again. </para> <para> A thread is never terminated while calling <parameter>func</parameter>, as supplied by <link linkend="g-thread-pool-new"><function>g_thread_pool_new()</function></link>. Instead the maximal number of threads only has effect for the allocation of new threads in <link linkend="g-thread-pool-push"><function>g_thread_pool_push()</function></link>. A new thread is allocated, whenever the number of currently running threads in <parameter>pool</parameter> is smaller than the maximal number. </para> <para> <parameter>error</parameter> can be <literal>NULL</literal> to ignore errors, or non-<literal>NULL</literal> to report errors. An error can only occur when a new thread couldn't be created.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><parameter>max_threads</parameter> :</term> <listitem><simpara> a new maximal number of threads for <parameter>pool</parameter> </simpara></listitem></varlistentry> <varlistentry><term><parameter>error</parameter> :</term> <listitem><simpara> return location for error </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-get-max-threads"/>g_thread_pool_get_max_threads ()</title> <indexterm><primary>g_thread_pool_get_max_threads</primary></indexterm><programlisting><link linkend="gint">gint</link> g_thread_pool_get_max_threads (<link linkend="GThreadPool">GThreadPool</link> *pool);</programlisting> <para> Returns the maximal number of threads for <parameter>pool</parameter>.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the maximal number of threads </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-get-num-threads"/>g_thread_pool_get_num_threads ()</title> <indexterm><primary>g_thread_pool_get_num_threads</primary></indexterm><programlisting><link linkend="guint">guint</link> g_thread_pool_get_num_threads (<link linkend="GThreadPool">GThreadPool</link> *pool);</programlisting> <para> Returns the number of threads currently running in <parameter>pool</parameter>.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the number of threads currently running </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-unprocessed"/>g_thread_pool_unprocessed ()</title> <indexterm><primary>g_thread_pool_unprocessed</primary></indexterm><programlisting><link linkend="guint">guint</link> g_thread_pool_unprocessed (<link linkend="GThreadPool">GThreadPool</link> *pool);</programlisting> <para> Returns the number of tasks still unprocessed in <parameter>pool</parameter>.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the number of unprocessed tasks </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-free"/>g_thread_pool_free ()</title> <indexterm><primary>g_thread_pool_free</primary></indexterm><programlisting><link linkend="void">void</link> g_thread_pool_free (<link linkend="GThreadPool">GThreadPool</link> *pool, <link linkend="gboolean">gboolean</link> immediate, <link linkend="gboolean">gboolean</link> wait);</programlisting> <para> Frees all resources allocated for <parameter>pool</parameter>. </para> <para> If <parameter>immediate</parameter> is <literal>TRUE</literal>, no new task is processed for <parameter>pool</parameter>. Otherwise <parameter>pool</parameter> is not freed before the last task is processed. Note however, that no thread of this pool is interrupted, while processing a task. Instead at least all still running threads can finish their tasks before the <parameter>pool</parameter> is freed. </para> <para> If <parameter>wait</parameter> is <literal>TRUE</literal>, the functions does not return before all tasks to be processed (dependent on <parameter>immediate</parameter>, whether all or only the currently running) are ready. Otherwise the function returns immediately. </para> <para> After calling this function <parameter>pool</parameter> must not be used anymore.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>pool</parameter> :</term> <listitem><simpara> a <link linkend="GThreadPool"><type>GThreadPool</type></link> </simpara></listitem></varlistentry> <varlistentry><term><parameter>immediate</parameter> :</term> <listitem><simpara> should <parameter>pool</parameter> shut down immediately? </simpara></listitem></varlistentry> <varlistentry><term><parameter>wait</parameter> :</term> <listitem><simpara> should the function wait for all tasks to be finished? </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-set-max-unused-threads"/>g_thread_pool_set_max_unused_threads ()</title> <indexterm><primary>g_thread_pool_set_max_unused_threads</primary></indexterm><programlisting><link linkend="void">void</link> g_thread_pool_set_max_unused_threads (<link linkend="gint">gint</link> max_threads);</programlisting> <para> Sets the maximal number of unused threads to <parameter>max_threads</parameter>. If <parameter>max_threads</parameter> is -1, no limit is imposed on the number of unused threads.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>max_threads</parameter> :</term> <listitem><simpara> maximal number of unused threads </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-get-max-unused-threads"/>g_thread_pool_get_max_unused_threads ()</title> <indexterm><primary>g_thread_pool_get_max_unused_threads</primary></indexterm><programlisting><link linkend="gint">gint</link> g_thread_pool_get_max_unused_threads (void);</programlisting> <para> Returns the maximal allowed number of unused threads.</para> <para> </para><variablelist role="params"> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the maximal number of unused threads </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-get-num-unused-threads"/>g_thread_pool_get_num_unused_threads ()</title> <indexterm><primary>g_thread_pool_get_num_unused_threads</primary></indexterm><programlisting><link linkend="guint">guint</link> g_thread_pool_get_num_unused_threads (void);</programlisting> <para> Returns the number of currently unused threads.</para> <para> </para><variablelist role="params"> <varlistentry><term><emphasis>Returns</emphasis> :</term><listitem><simpara> the number of currently unused threads </simpara></listitem></varlistentry> </variablelist></refsect2> <refsect2> <title><anchor id="g-thread-pool-stop-unused-threads"/>g_thread_pool_stop_unused_threads ()</title> <indexterm><primary>g_thread_pool_stop_unused_threads</primary></indexterm><programlisting><link linkend="void">void</link> g_thread_pool_stop_unused_threads (void);</programlisting> <para> Stops all currently unused threads. This does not change the maximal number of unused threads. This function can be used to regularly stop all unused threads e.g. from <link linkend="g-timeout-add"><function>g_timeout_add()</function></link>.</para> <para> </para></refsect2> </refsect1> <refsect1> <title>See Also</title> <para> <variablelist> <varlistentry> <term><link linkend="GThread"><type>GThread</type></link></term> <listitem><para>GLib thread system.</para></listitem> </varlistentry> </variablelist> </para> </refsect1> </refentry>