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

📄 threads.sgml

📁 GLib是GTK+和GNOME工程的基础底层核心程序库
💻 SGML
📖 第 1 页 / 共 3 页
字号:
g_mutex_new() requires that. Use a #GStaticMutex instead.</para><para>A #GMutex should only be accessed via the following functions.</para><note><para>All of the <function>g_mutex_*</function> functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.</para></note><!-- ##### FUNCTION g_mutex_new ##### --><para>Creates a new #GMutex. </para><note><para>This function will abort, if g_thread_init() has not been called yet.</para></note>@Returns: a new #GMutex.<!-- ##### FUNCTION g_mutex_lock ##### --><para>Locks @mutex. If @mutex is already locked by another thread, thecurrent thread will block until @mutex is unlocked by the otherthread.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will do nothing then.</para><note><para>#GMutex is not recursive, i.e. a thread will deadlock, if it alreadyhas locked @mutex while calling g_mutex_lock(). Use#GStaticRecMutex instead, if you need recursive mutexes.</para></note>@mutex: a #GMutex.<!-- ##### FUNCTION g_mutex_trylock ##### --><para>Tries to lock @mutex. If @mutex is already locked by anotherthread, it immediately returns %FALSE. Otherwise it locks @mutexand returns %TRUE.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will immediately return %TRUE then.</para><note><para>#GMutex is not recursive, i.e. g_mutex_trylock() will return %FALSE,if the current thread already has locked @mutex. Use#GStaticRecMutex instead, if you need recursive mutexes.</para></note>@mutex: a #GMutex.@Returns: %TRUE, if @mutex could be locked.<!-- ##### FUNCTION g_mutex_unlock ##### --><para>Unlocks @mutex. If another thread is blocked in a g_mutex_lock() callfor @mutex, it will be woken and can lock @mutex itself.</para><para>This function can also be used, if g_thread_init() has not yet beencalled and will do nothing then.</para>@mutex: a #GMutex.<!-- ##### FUNCTION g_mutex_free ##### --><para>Destroys @mutex.</para>@mutex: a #GMutex.<!-- ##### STRUCT GStaticMutex ##### --><para>A #GStaticMutex works like a #GMutex, but it has one significantadvantage. It doesn't need to be created at run-time like a #GMutex,but can be defined at compile-time. Here is a shorter, easier andsafer version of our <function>give_me_next_number()</function> example:</para><para><example><title>Using <structname>GStaticMutex</structname> to simplify thread-safe programming</title><programlisting>  int give_me_next_number (<!>)  {    static int current_number = 0;    int ret_val;    static GStaticMutex mutex = G_STATIC_MUTEX_INIT;    g_static_mutex_lock (&amp;mutex);    ret_val = current_number = calc_next_number (current_number);     g_static_mutex_unlock (&amp;mutex);    return ret_val;  }</programlisting></example></para><para>Sometimes you would like to dynamically create a mutex. If you don'twant to require prior calling to g_thread_init(), because your codeshould also be usable in non-threaded programs, you are not able touse g_mutex_new() and thus #GMutex, as that requires a prior call tog_thread_init(). In theses cases you can also use a #GStaticMutex. Itmust be initialized with g_static_mutex_init() before using it andfreed with with g_static_mutex_free() when not needed anymore to freeup any allocated resources.</para><para>Even though #GStaticMutex is not opaque, it should only be used withthe following functions, as it is defined differently on differentplatforms.</para><para>All of the <function>g_static_mutex_*</function> functions can also be used, if g_thread_init() has not yet been called.</para><note><para>All of the <function>g_static_mutex_*</function> functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.</para></note><!-- ##### MACRO G_STATIC_MUTEX_INIT ##### --><para>A #GStaticMutex must be initialized with this macro, before it can beused. This macro can used be to initialize a variable, but it cannotbe assigned to a variable. In that case you have to useg_static_mutex_init().</para><para><informalexample><programlisting>GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;</programlisting></informalexample></para><!-- ##### FUNCTION g_static_mutex_init ##### --><para>Initializes @mutex. Alternatively you can initialize it with#G_STATIC_MUTEX_INIT.</para>@mutex: a #GStaticMutex to be initialized.<!-- ##### FUNCTION g_static_mutex_lock ##### --><para>Works like g_mutex_lock(), but for a #GStaticMutex.</para>@mutex: a #GStaticMutex.<!-- ##### FUNCTION g_static_mutex_trylock ##### --><para>Works like g_mutex_trylock(), but for a #GStaticMutex.</para>@mutex: a #GStaticMutex.@Returns: %TRUE, if the #GStaticMutex could be locked.<!-- ##### FUNCTION g_static_mutex_unlock ##### --><para>Works like g_mutex_unlock(), but for a #GStaticMutex.</para>@mutex: a #GStaticMutex.<!-- ##### FUNCTION g_static_mutex_get_mutex ##### --><para>For some operations (like g_cond_wait()) you must have a #GMutexinstead of a #GStaticMutex. This function will return thecorresponding #GMutex for @mutex.</para>@mutex: a #GStaticMutex.@Returns: the #GMutex corresponding to @mutex.<!-- ##### FUNCTION g_static_mutex_free ##### --><para>Releases all resources allocated to @mutex. </para><para>You don't have to call this functions for a #GStaticMutex with anunbounded lifetime, i.e. objects declared 'static', but if you have a#GStaticMutex as a member of a structure and the structure is freed,you should also free the #GStaticMutex.</para>@mutex: a #GStaticMutex to be freed.<!-- ##### MACRO G_LOCK_DEFINE ##### --><para>The %G_LOCK_* macros provide a convenient interface to #GStaticMutexwith the advantage that they will expand to nothing in programscompiled against a thread-disabled GLib, saving code and memorythere. #G_LOCK_DEFINE defines a lock. It can appear, where variabledefinitions may appear in programs, i.e. in the first block of afunction or outside of functions. The @name parameter will be mangledto get the name of the #GStaticMutex. This means, that you can usenames of existing variables as the parameter, e.g. the name of thevariable you intent to protect with the lock. Look at our<function>give_me_next_number()</function> example using the %G_LOCK_* macros:</para><para><example><title>Using the %G_LOCK_* convenience macros</title><programlisting>G_LOCK_DEFINE (current_number);int give_me_next_number (<!>)  {    static int current_number = 0;    int ret_val;    G_LOCK (current_number);    ret_val = current_number = calc_next_number (current_number);     G_UNLOCK (current_number);    return ret_val;  }</programlisting></example></para>@name: the name of the lock.<!-- ##### MACRO G_LOCK_DEFINE_STATIC ##### --><para>This works like #G_LOCK_DEFINE, but it creates a static object.</para>@name: the name of the lock.<!-- ##### MACRO G_LOCK_EXTERN ##### --><para>This declares a lock, that is defined with #G_LOCK_DEFINE in another module.</para>@name: the name of the lock.<!-- ##### MACRO G_LOCK ##### --><para>Works like g_mutex_lock(), but for a lock defined with #G_LOCK_DEFINE.</para>@name: the name of the lock.<!-- ##### MACRO G_TRYLOCK ##### --><para>Works like g_mutex_trylock(), but for a lock defined with #G_LOCK_DEFINE.</para>@name: the name of the lock.@Returns: %TRUE, if the lock could be locked.<!-- ##### MACRO G_UNLOCK ##### --><para>Works like g_mutex_unlock(), but for a lock defined with #G_LOCK_DEFINE.</para>@name: the name of the lock.<!-- ##### STRUCT GStaticRecMutex ##### --><para>A #GStaticRecMutex works like a #GStaticMutex, but it can be lockedmultiple times by one thread. If you enter it n times, however, youhave to unlock it n times again to let other threads lock it. Anexception is the function g_static_rec_mutex_unlock_full(), thatallows you to unlock a #GStaticRecMutex completely returning the depth,i.e. the number of times this mutex was locked. The depth can later beused to restore the state by calling g_static_rec_mutex_lock_full().</para><para>Even though #GStaticRecMutex is not opaque, it should only be used withthe following functions.</para><para>All of the <function>g_static_rec_mutex_*</function> functions can also be used, if g_thread_init() has not been called.</para>@mutex: @depth: @owner: <!-- ##### MACRO G_STATIC_REC_MUTEX_INIT ##### --><para>A #GStaticRecMutex 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_rec_mutex_init().</para><para><informalexample><programlisting>GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;</programlisting></informalexample></para><!-- ##### FUNCTION g_static_rec_mutex_init ##### --><para>A #GStaticRecMutex must be initialized with this function, before itcan be used. Alternatively you can initialize it with#G_STATIC_REC_MUTEX_INIT.</para>@mutex: a #GStaticRecMutex to be initialized.<!-- ##### FUNCTION g_static_rec_mutex_lock ##### --><para>Locks @mutex. If @mutex is already locked by another thread, thecurrent thread will block until @mutex is unlocked by the otherthread. If @mutex is already locked by the calling thread, thisfunctions increases the depth of @mutex and returns immediately.</para>@mutex: a #GStaticRecMutex to lock.<!-- ##### FUNCTION g_static_rec_mutex_trylock ##### --><para>Tries to lock @mutex. If @mutex is already locked by another thread,it immediately returns %FALSE. Otherwise it locks @mutex and returns%TRUE. If @mutex is already locked by the calling thread, thisfunctions increases the depth of @mutex and immediately  returns %TRUE.</para>@mutex: a #GStaticRecMutex to lock.@Returns: %TRUE, if @mutex could be locked.<!-- ##### FUNCTION g_static_rec_mutex_unlock ##### --><para>Unlocks @mutex. Another threads can, however, only lock @mutex when ithas been unlocked as many times, as it had been locked before. If@mutex is completely unlocked and another thread is blocked in ag_static_rec_mutex_lock() call for @mutex, it will be woken and canlock @mutex itself.</para>@mutex: a #GStaticRecMutex to unlock.<!-- ##### FUNCTION g_static_rec_mutex_lock_full ##### --><para>Works like calling g_static_rec_mutex_lock() for @mutex @depth times.</para>@mutex: a #GStaticRecMutex to lock.@depth: number of times this mutex has to be unlocked to be completely unlocked.<!-- ##### FUNCTION g_static_rec_mutex_unlock_full ##### --><para>Completely unlocks @mutex. If another thread is blocked in ag_static_rec_mutex_lock() call for @mutex, it will be woken and canlock @mutex itself. This function returns the number of times, that@mutex has been locked by the current thread. To restore the statebefore the call to g_static_rec_mutex_unlock_full() you can callg_static_rec_mutex_lock_full() with the depth returned by thisfunction.</para>@mutex: a #GStaticRecMutex to completely unlock.@Returns: number of times @mutex has been locked by the current thread.<!-- ##### FUNCTION g_static_rec_mutex_free ##### --><para>Releases all resources allocated to a #GStaticRecMutex.</para><para>You don't have to call this functions for a #GStaticRecMutex with anunbounded lifetime, i.e. objects declared 'static', but if you have a#GStaticRecMutex as a member of a structure and the structure isfreed, you should also free the #GStaticRecMutex.</para>@mutex: a #GStaticRecMutex to be freed.<!-- ##### STRUCT GStaticRWLock ##### --><para>The #GStaticRWLock struct represents a read-write lock. A read-writelock can be used for protecting data, that some portions of code onlyread from, while others also write. In such situations it isdesirable, that several readers can read at once, whereas of courseonly one writer may write at a time. Take a look at the followingexample:<example><title>An array with access functions</title><programlisting>  GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;  GPtrArray *array;  gpointer my_array_get (guint index)  {    gpointer retval = NULL;    if (!array)      return NULL;    g_static_rw_lock_reader_lock (&amp;rwlock);    if (index < array->len)      retval = g_ptr_array_index (array, index);    g_static_rw_lock_reader_unlock (&amp;rwlock);    return retval;  }  void my_array_set (guint index, gpointer data)  {    g_static_rw_lock_writer_lock (&amp;rwlock);    if (!array)      array = g_ptr_array_new ();    if (index >= array->len)      g_ptr_array_set_size (array, index+1);    g_ptr_array_index (array, index) = data;     g_static_rw_lock_writer_unlock (&amp;rwlock);  }</programlisting></example></para><para>This example shows an array, which can be accessed by many readers(the <function>my_array_get()</function> function) simultaneously, whereas the writers (the <function>my_array_set()</function> function) will only be allowed once a time and only if no readers currently access the array. This is because of the potentially dangerous resizing of the array. Using these functions is fully multi-thread safe now. </para><para>Most of the time the writers should have precedence of readers. Thatmeans for this implementation, that as soon as a writer wants to lockthe data, no other reader is allowed to lock the data, whereas ofcourse the readers, that already have locked the data are allowed tofinish their operation. As soon as the last reader unlocks the data,the writer will lock it.</para><para>Even though #GStaticRWLock is not opaque, it should only be used withthe following functions.</para><para>All of the <function>g_static_rw_lock_*</function> functions can also be used, if g_thread_init() has not been called.</para><note><para>A read-write lock has a higher overhead as a mutex. For example bothg_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock()have to lock and unlock a #GStaticMutex, so it takes at least twice thetime to lock and unlock a #GStaticRWLock than to lock and unlock a

⌨️ 快捷键说明

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