📄 glib-threads.html
字号:
{ static int current_number = 0; /* now do a very complicated calculation to calculate the new number, this might for example be a random number generator */ current_number = calc_next_number (current_number); return current_number; }</pre></div></div><p><br class="example-break"></p><p>It is easy to see that this won't work in a multi-threadedapplication. There current_number must be protected against sharedaccess. A first naive implementation would be:</p><p></p><div class="example"><a name="id2885385"></a><p class="title"><b>Example 3. The wrong way to write a thread-safe function</b></p><div class="example-contents"><pre class="programlisting"> int give_me_next_number () { static int current_number = 0; int ret_val; static GMutex * mutex = NULL; if (!mutex) mutex = g_mutex_new (); g_mutex_lock (mutex); ret_val = current_number = calc_next_number (current_number); g_mutex_unlock (mutex); return ret_val; }</pre></div></div><p><br class="example-break"></p><p>This looks like it would work, but there is a race condition whileconstructing the mutex and this code cannot work reliable. Please donot use such constructs in your own programs! One working solution is:</p><p></p><div class="example"><a name="id2885418"></a><p class="title"><b>Example 4. A correct thread-safe function</b></p><div class="example-contents"><pre class="programlisting"> static GMutex *give_me_next_number_mutex = NULL; /* this function must be called before any call to give_me_next_number () it must be called exactly once. */ void init_give_me_next_number () { g_assert (give_me_next_number_mutex == NULL); give_me_next_number_mutex = g_mutex_new (); } int give_me_next_number () { static int current_number = 0; int ret_val; g_mutex_lock (give_me_next_number_mutex); ret_val = current_number = calc_next_number (current_number); g_mutex_unlock (give_me_next_number_mutex); return ret_val; }</pre></div></div><p><br class="example-break"></p><p><a class="link" href="glib-Threads.html#GStaticMutex"><span class="type">GStaticMutex</span></a> provides a simpler and safer way of doing this.</p><p>If you want to use a mutex, and your code should also work withoutcalling <a class="link" href="glib-Threads.html#g-thread-init"><code class="function">g_thread_init()</code></a> first, then you can not use a <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>, as<a class="link" href="glib-Threads.html#g-mutex-new"><code class="function">g_mutex_new()</code></a> requires that the thread system be initialized. Use a<a class="link" href="glib-Threads.html#GStaticMutex"><span class="type">GStaticMutex</span></a> instead.</p><p>A <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a> should only be accessed via the following functions.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>All of the <code class="function">g_mutex_*</code> functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.</p></div></div><hr><div class="refsect2" lang="en"><a name="id2885534"></a><h3><a name="g-mutex-new"></a>g_mutex_new ()</h3><a class="indexterm" name="id2885547"></a><pre class="programlisting"><a class="link" href="glib-Threads.html#GMutex">GMutex</a>* g_mutex_new ();</pre><p>Creates a new <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>. </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>This function will abort if <a class="link" href="glib-Threads.html#g-thread-init"><code class="function">g_thread_init()</code></a> has not been called yet.</p></div><div class="variablelist"><table border="0"><col align="left" valign="top"><tbody><tr><td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td><td>a new <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>.</td></tr></tbody></table></div></div><hr><div class="refsect2" lang="en"><a name="id2885617"></a><h3><a name="g-mutex-lock"></a>g_mutex_lock ()</h3><a class="indexterm" name="id2885630"></a><pre class="programlisting">void g_mutex_lock (<a class="link" href="glib-Threads.html#GMutex">GMutex</a> *mutex);</pre><p>Locks <em class="parameter"><code>mutex</code></em>. If <em class="parameter"><code>mutex</code></em> is already locked by another thread, thecurrent thread will block until <em class="parameter"><code>mutex</code></em> is unlocked by the otherthread.</p><p>This function can be used even if <a class="link" href="glib-Threads.html#g-thread-init"><code class="function">g_thread_init()</code></a> has not yet beencalled, and, in that case, will do nothing.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p><a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a> is neither guaranteed to be recursive nor to be non-recursive,i.e. a thread could deadlock while calling <a class="link" href="glib-Threads.html#g-mutex-lock"><code class="function">g_mutex_lock()</code></a>, if italready has locked <em class="parameter"><code>mutex</code></em>. Use <a class="link" href="glib-Threads.html#GStaticRecMutex"><span class="type">GStaticRecMutex</span></a>, if you need recursivemutexes.</p></div><div class="variablelist"><table border="0"><col align="left" valign="top"><tbody><tr><td><p><span class="term"><em class="parameter"><code>mutex</code></em> :</span></p></td><td>a <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>.</td></tr></tbody></table></div></div><hr><div class="refsect2" lang="en"><a name="id2885761"></a><h3><a name="g-mutex-trylock"></a>g_mutex_trylock ()</h3><a class="indexterm" name="id2885774"></a><pre class="programlisting"><a class="link" href="glib-Basic-Types.html#gboolean">gboolean</a> g_mutex_trylock (<a class="link" href="glib-Threads.html#GMutex">GMutex</a> *mutex);</pre><p>Tries to lock <em class="parameter"><code>mutex</code></em>. If <em class="parameter"><code>mutex</code></em> is already locked by anotherthread, it immediately returns <a class="link" href="glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a>. Otherwise it locks <em class="parameter"><code>mutex</code></em>and returns <a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>.</p><p>This function can be used even if <a class="link" href="glib-Threads.html#g-thread-init"><code class="function">g_thread_init()</code></a> has not yet beencalled, and, in that case, will immediately return <a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p><a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a> is neither guaranteed to be recursive nor to be non-recursive,i.e. the return value of <a class="link" href="glib-Threads.html#g-mutex-trylock"><code class="function">g_mutex_trylock()</code></a> could be both <a class="link" href="glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> or<a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, if the current thread already has locked <em class="parameter"><code>mutex</code></em>. Use<a class="link" href="glib-Threads.html#GStaticRecMutex"><span class="type">GStaticRecMutex</span></a>, if you need recursive mutexes.</p></div><div class="variablelist"><table border="0"><col align="left" valign="top"><tbody><tr><td><p><span class="term"><em class="parameter"><code>mutex</code></em> :</span></p></td><td>a <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>.</td></tr><tr><td><p><span class="term"><span class="emphasis"><em>Returns</em></span> :</span></p></td><td><a class="link" href="glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, if <em class="parameter"><code>mutex</code></em> could be locked.</td></tr></tbody></table></div></div><hr><div class="refsect2" lang="en"><a name="id2885981"></a><h3><a name="g-mutex-unlock"></a>g_mutex_unlock ()</h3><a class="indexterm" name="id2885994"></a><pre class="programlisting">void g_mutex_unlock (<a class="link" href="glib-Threads.html#GMutex">GMutex</a> *mutex);</pre><p>Unlocks <em class="parameter"><code>mutex</code></em>. If another thread is blocked in a <a class="link" href="glib-Threads.html#g-mutex-lock"><code class="function">g_mutex_lock()</code></a> callfor <em class="parameter"><code>mutex</code></em>, it will be woken and can lock <em class="parameter"><code>mutex</code></em> itself.</p><p>This function can be used even if <a class="link" href="glib-Threads.html#g-thread-init"><code class="function">g_thread_init()</code></a> has not yet beencalled, and, in that case, will do nothing.</p><div class="variablelist"><table border="0"><col align="left" valign="top"><tbody><tr><td><p><span class="term"><em class="parameter"><code>mutex</code></em> :</span></p></td><td>a <a class="link" href="glib-Threads.html#GMutex"><span class="type">GMutex</span></a>.</td></tr></tbody></table></div></div><hr><div class="refsect2" lang="en"><a name="id2886094"></a><h3><a name="g-mutex-free"></a>g
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -