⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threads.sgml

📁 GLib是GTK+和GNOME工程的基础底层核心程序库
💻 SGML
📖 第 1 页 / 共 3 页
字号:
#GStaticMutex. So only data structures, that are accessed by multiplereaders, which keep the lock for a considerable time justify a#GStaticRWLock. The above example most probably would fare better witha #GStaticMutex.</para></note>@mutex: @read_cond: @write_cond: @read_counter: @write: @want_to_read: @want_to_write: <!-- ##### MACRO G_STATIC_RW_LOCK_INIT ##### --><para>A #GStaticRWLock must be initialized with this macro, before it canbe used. This macro can used be to initialize a variable, but itcannot be assigned to a variable. In that case you have to useg_static_rw_lock_init().</para><para><informalexample><programlisting>GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;</programlisting></informalexample></para><!-- ##### FUNCTION g_static_rw_lock_init ##### --><para>A #GStaticRWLock must be initialized with this function, before it canbe used. Alternatively you can initialize it with#G_STATIC_RW_LOCK_INIT.</para>@lock: a #GStaticRWLock to be initialized.<!-- ##### FUNCTION g_static_rw_lock_reader_lock ##### --><para>Locks @lock for reading. There may be unlimited concurrent locks forreading of a #GStaticRWLock at the same time.  If @lock is alreadylocked for writing by another thread or if another thread is alreadywaiting to lock @lock for writing, this function will block until@lock is unlocked by the other writing thread and no other writingthreads want to lock @lock. This lock has to be unlocked byg_static_rw_lock_reader_unlock().</para><para>#GStaticRWLock is not recursive. It might seem to be possible torecursivly 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 (&amp;current_number_key);    if (!current_number)    {      current_number = g_new (int,1);      *current_number = 0;      g_static_private_set (&amp;current_number_key, current_number, g_free);    }    *current_number = calc_next_number (*current_number);     return *current_number;  }</programlisting></example></para>@index: <!-- ##### 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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -