📄 threads.sgml
字号:
</para><para>#GStaticRWLock is not recursive. It might seem to be possible torecursively lock for reading, but that can result in a deadlock aswell, due to writer preference.</para>@lock: a #GStaticRWLock to lock for reading.<!-- ##### FUNCTION g_static_rw_lock_reader_trylock ##### --><para>Tries to lock @lock for reading. If @lock is already locked forwriting by another thread or if another thread is already waiting tolock @lock for writing, it immediately returns %FALSE. Otherwise itlocks @lock for reading and returns %TRUE. This lock has to be unlockedby g_static_rw_lock_reader_unlock().</para>@lock: a #GStaticRWLock to lock for reading.@Returns: %TRUE, if @lock could be locked for reading.<!-- ##### FUNCTION g_static_rw_lock_reader_unlock ##### --><para>Unlocks @lock. If a thread waits to lock @lock for writing and alllocks for reading have been unlocked, the waiting thread is woken upand can lock @lock for writing.</para>@lock: a #GStaticRWLock to unlock after reading.<!-- ##### FUNCTION g_static_rw_lock_writer_lock ##### --><para>Locks @lock for writing. If @lock is already locked for writing orreading by other threads, this function will block until @lock iscompletely unlocked and then lock @lock for writing. While thisfunctions waits to lock @lock, no other thread can lock @lock forreading. When @lock is locked for writing, no other thread can lock@lock (neither for reading nor writing). This lock has to be unlockedby g_static_rw_lock_writer_unlock().</para>@lock: a #GStaticRWLock to lock for writing.<!-- ##### FUNCTION g_static_rw_lock_writer_trylock ##### --><para>Tries to lock @lock for writing. If @lock is already locked (foreither reading or writing) by another thread, it immediately returns%FALSE. Otherwise it locks @lock for writing and returns %TRUE. Thislock has to be unlocked by g_static_rw_lock_writer_unlock().</para>@lock: a #GStaticRWLock to lock for writing.@Returns: %TRUE, if @lock could be locked for writing.<!-- ##### FUNCTION g_static_rw_lock_writer_unlock ##### --><para>Unlocks @lock. If a thread waits to lock @lock for writing and alllocks for reading have been unlocked, the waiting thread is woken upand can lock @lock for writing. If no thread waits to lock @lock forwriting and threads wait to lock @lock for reading, the waitingthreads are woken up and can lock @lock for reading.</para>@lock: a #GStaticRWLock to unlock after writing.<!-- ##### FUNCTION g_static_rw_lock_free ##### --><para>Releases all resources allocated to @lock. </para><para>You don't have to call this functions for a #GStaticRWLock with anunbounded lifetime, i.e. objects declared 'static', but if you have a#GStaticRWLock as a member of a structure and the structure is freed,you should also free the #GStaticRWLock.</para>@lock: a #GStaticRWLock to be freed.<!-- ##### STRUCT GCond ##### --><para>The #GCond struct is an opaque data structure to represent acondition. A #GCond is an object, that threads can block on, if theyfind a certain condition to be false. If other threads change thestate of this condition they can signal the #GCond, such that thewaiting thread is woken up. </para><para><example><title>Using GCond to block a thread until a condition is satisfied</title><programlisting>GCond* data_cond = NULL; /* Must be initialized somewhere */GMutex* data_mutex = NULL; /* Must be initialized somewhere */gpointer current_data = NULL;void push_data (gpointer data){ g_mutex_lock (data_mutex); current_data = data; g_cond_signal (data_cond); g_mutex_unlock (data_mutex);}gpointer pop_data (<!-- -->){ gpointer data; g_mutex_lock (data_mutex); while (!current_data) g_cond_wait (data_cond, data_mutex); data = current_data; current_data = NULL; g_mutex_unlock (data_mutex); return data;}</programlisting></example></para><para>Whenever a thread calls <function>pop_data()</function> now, it will wait until current_data is non-%NULL, i.e. until some other thread has called <function>push_data()</function>.</para><note><para>It is important to use the g_cond_wait() and g_cond_timed_wait()functions only inside a loop, which checks for the condition to betrue as it is not guaranteed that the waiting thread will find itfulfilled, even if the signaling thread left the conditionin that state. This is because another thread can have altered thecondition, before the waiting thread got the chance to be woken up,even if the condition itself is protected by a #GMutex, like above.</para></note><para>A #GCond should only be accessed via the following functions.</para><note><para>All of the <function>g_cond_*</function> functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.</para></note><!-- ##### FUNCTION g_cond_new ##### --><para>Creates a new #GCond. This function will abort, if g_thread_init()has not been called yet.</para>@Returns: a new #GCond.<!-- ##### FUNCTION g_cond_signal ##### --><para>If threads are waiting for @cond, exactly one of them is woken up. Itis good practice to hold the same lock as the waiting thread, whilecalling this function, though not required.</para><para>This function can also be used, if g_thread_init() hasnot yet been called and will do nothing then.</para>@cond: a #GCond.<!-- ##### FUNCTION g_cond_broadcast ##### --><para>If threads are waiting for @cond, all of them are woken up. It is goodpractice to lock the same mutex as the waiting threads, while callingthis function, though not required.</para><para>This function can also be used, if g_thread_init() hasnot yet been called and will do nothing then.</para>@cond: a #GCond.<!-- ##### FUNCTION g_cond_wait ##### --><para>Waits until this thread is woken up on @cond. The @mutex is unlockedbefore falling asleep and locked again before resuming.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will immediately return then.</para>@cond: a #GCond.@mutex: a #GMutex, that is currently locked.<!-- ##### FUNCTION g_cond_timed_wait ##### --><para>Waits until this thread is woken up on @cond, but not longer thanuntil the time, that is specified by @abs_time. The @mutex isunlocked before falling asleep and locked again before resuming.</para><para>If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will immediately return %TRUE then.</para><para>To easily calculate @abs_time a combination of g_get_current_time()and g_time_val_add() can be used.</para>@cond: a #GCond.@mutex: a #GMutex, that is currently locked.@abs_time: a #GTimeVal, determining the final time.@Returns: %TRUE, if the thread is woken up in time.<!-- ##### FUNCTION g_cond_free ##### --><para>Destroys the #GCond.</para>@cond: a #GCond.<!-- ##### STRUCT GPrivate ##### --><para>The #GPrivate struct is an opaque data structure to represent a threadprivate data key. Threads can thereby obtain and set a pointer, whichis private to the current thread. Take our <function>give_me_next_number()</function> example from above. Now we don't want <literal>current_number</literal> to be sharedbetween the threads, but to be private to each thread. This can bedone as follows:<example><title>Using GPrivate for per-thread data</title><programlisting> GPrivate* current_number_key = NULL; /* Must be initialized somewhere */ /* with g_private_new (g_free); */ int give_me_next_number (<!-- -->) { int *current_number = g_private_get (current_number_key); if (!current_number) { current_number = g_new (int,1); *current_number = 0; g_private_set (current_number_key, current_number); } *current_number = calc_next_number (*current_number); return *current_number; }</programlisting></example></para><para>Here the pointer belonging to the key <literal>current_number_key</literal> is read. If it is %NULL, it has not been set yet. Then get memory for an integer value, assign this memory to the pointer and write the pointerback. Now we have an integer value, that is private to the current thread.</para><para>The #GPrivate struct should only be accessed via the following functions.</para><note><para>All of the <function>g_private_*</function> functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.</para></note><!-- ##### FUNCTION g_private_new ##### --><para>Creates a new #GPrivate. If @destructor is non-%NULL, it is a pointerto a destructor function. Whenever a thread ends and the correspondingpointer keyed to this instance of #GPrivate is non-%NULL, thedestructor is called with this pointer as the argument.</para><note><para>@destructor is working quite differently from @notify ing_static_private_set().</para></note><note><para>A #GPrivate can not be freed. Reuse it instead, if you can to avoidshortage or use #GStaticPrivate.</para></note><note><para>This function will abort, if g_thread_init() has not been called yet.</para></note>@destructor: a function to handle the data keyed to #GPrivate, when athread ends.@Returns: a new #GPrivate.<!-- ##### FUNCTION g_private_get ##### --><para>Returns the pointer keyed to @private_key for the current thread. Thispointer is %NULL, when g_private_set() hasn't been called for thecurrent @private_key and thread yet.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will return the value of @private_key casted to #gpointer then.</para>@private_key: a #GPrivate.@Returns: the corresponding pointer.<!-- ##### FUNCTION g_private_set ##### --><para>Sets the pointer keyed to @private_key for the current thread.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will set @private_key to @data casted to #GPrivate* then.</para>@private_key: a #GPrivate.@data: the new pointer.<!-- ##### STRUCT GStaticPrivate ##### --><para>A #GStaticPrivate works almost like a #GPrivate, but it has onesignificant advantage. It doesn't need to be created at run-time likea #GPrivate, but can be defined at compile-time. This is similar tothe difference between #GMutex and #GStaticMutex. Now look at our<function>give_me_next_number()</function> example with #GStaticPrivate:</para><para><example><title>Using GStaticPrivate for per-thread data</title><programlisting> int give_me_next_number (<!-- -->) { static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT; int *current_number = g_static_private_get (&current_number_key); if (!current_number) { current_number = g_new (int,1); *current_number = 0; g_static_private_set (&current_number_key, current_number, g_free); } *current_number = calc_next_number (*current_number); return *current_number; }</programlisting></example></para><!-- ##### MACRO G_STATIC_PRIVATE_INIT ##### --><para>Every #GStaticPrivate must be initialized with this macro, before it canbe used.</para><para><informalexample><programlisting>GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;</programlisting></informalexample></para><!-- ##### FUNCTION g_static_private_init ##### --><para>Initializes @private_key. Alternatively you can initialize it with#G_STATIC_PRIVATE_INIT.</para>@private_key: a #GStaticPrivate to be initialized.<!-- ##### FUNCTION g_static_private_get ##### --><para>Works like g_private_get() only for a #GStaticPrivate.</para><para>This function also works, if g_thread_init() has not yet been called.</para>@private_key: a #GStaticPrivate.@Returns: the corresponding pointer.<!-- ##### FUNCTION g_static_private_set ##### --><para>Sets the pointer keyed to @private_key for the current thread and thefunction @notify to be called with that pointer (%NULL or non-%NULL),whenever the pointer is set again or whenever the current thread ends.</para><para>This function also works, if g_thread_init() has not yet beencalled. If g_thread_init() is called later, the @data keyed to@private_key will be inherited only by the main thread, i.e. the one thatcalled g_thread_init().</para><note><para>@notify is working quite differently from @destructor ing_private_new().</para></note>@private_key: a #GStaticPrivate.@data: the new pointer.@notify: a function to be called with the pointer, whenever thecurrent thread ends or sets this pointer again.<!-- ##### FUNCTION g_static_private_free ##### --><para>Releases all resources allocated to @private_key. </para><para>You don't have to call this functions for a #GStaticPrivate with anunbounded lifetime, i.e. objects declared 'static', but if you have a#GStaticPrivate as a member of a structure and the structure is freed,you should also free the #GStaticPrivate.</para>@private_key: a #GStaticPrivate to be freed.<!-- ##### STRUCT GOnce ##### --><para>A <structname>GOnce</structname> struct controls a one-time initialization function. Any one-time initialization function must have its own unique <structname>GOnce</structname> struct.</para>@status: @retval: @Since: 2.4<!-- ##### ENUM GOnceStatus ##### --><para>The possible stati of a one-time initialization function controlled by a #GOnce struct.</para>@G_ONCE_STATUS_NOTCALLED: the function has not been called yet.@G_ONCE_STATUS_PROGRESS: the function call is currently in progress.@G_ONCE_STATUS_READY: the function has been called.@Since: 2.4<!-- ##### MACRO G_ONCE_INIT ##### --><para>A #GOnce must be initialized with this macro, before it can be used. </para><para><informalexample><programlisting>GOnce my_once = G_ONCE_INIT;</programlisting></informalexample></para>@Since: 2.4<!-- ##### MACRO g_once ##### --><para>The first call to this routine by a process with a given #GOnce struct calls @func with the given argument. Thereafter, subsequent calls to g_once() with the same #GOnce struct do not call @func again, but return the stored result of the first call. On return from g_once(), the status of @oncewill be %G_ONCE_STATUS_READY.</para><para>For example, a mutex or a thread-specific data key must be created exactly once. In a threaded environment, calling g_once() ensures that the initialization is serialized across multiple threads.</para><note><para>Calling g_once() recursively on the same #GOnce struct in @func will lead to a deadlock.</para></note><para><informalexample><programlisting>gpointer get_debug_flags (){ static GOnce my_once = G_ONCE_INIT; g_once (&my_once, parse_debug_flags, NULL); return my_once.retval;}</programlisting></informalexample></para>@once: a #GOnce structure@func: the function associated to @once. This function is called only once, regardless of the number of times it and its associated #GOnce struct are passed to g_once() .@arg: data to be passed to @func@Since: 2.4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -