📄 threads.sgml
字号:
true. It is not guaranteed that the waiting thread will find thecondition fulfilled after it wakes up, even if the signaling threadleft the condition in that state: another thread may 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 be used even if g_thread_init() has not yet been called,and, in that case, will do nothing.</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 be used even if g_thread_init() has not yet been called,and, in that case, will do nothing.</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 be used even if g_thread_init() has not yet beencalled, and, in that case, will immediately return.</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 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 be used even if g_thread_init() has not yet beencalled, and, in that case, will immediately return %TRUE.</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 @cond was signalled, or %FALSE on timeout.<!-- ##### 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. Suppose we don't want <literal>current_number</literal> to be sharedbetween the threads, but instead 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 used 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 destroy 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.If g_private_set() hasn't been called for thecurrent @private_key and thread yet, this pointer will be %NULL.</para><para>This function can be used even if g_thread_init() has not yet beencalled, and, in that case, will return the value of @private_key casted to #gpointer.</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 be used even if g_thread_init() has not yet beencalled, and, in that case, will set @private_key to @data casted to #GPrivate*.</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 works even 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 works even 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 used 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: the status of the #GOnce@retval: the value returned by the call to the function, if @status is %G_ONCE_STATUS_READY@Since: 2.4<!-- ##### ENUM GOnceStatus ##### --><para>The possible statuses 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 @once will 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 #GThreadFunc 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 + -