GLib Reference Manual: Deprecated thread API

## Deprecated thread API Deprecated thread API — old thread APIs (for reference only) |

## Functions

void | g_thread_init ()
gboolean | g_thread_supported ()
gboolean | g_thread_get_initialized ()
GThread * | g_thread_create ()
GThread * | g_thread_create_full ()
void | g_thread_set_priority ()
void | g_thread_foreach ()
GMutex * | g_mutex_new ()
void | g_mutex_free ()
GCond* | g_cond_new ()
void | g_cond_free ()
GPrivate * | g_private_new ()
void | g_static_mutex_init ()
void | g_static_mutex_lock ()
gboolean | g_static_mutex_trylock ()
void | g_static_mutex_unlock ()
GMutex * | g_static_mutex_get_mutex ()
void | g_static_mutex_free ()
void | g_static_rec_mutex_init ()
void | g_static_rec_mutex_lock ()
gboolean | g_static_rec_mutex_trylock ()
void | g_static_rec_mutex_unlock ()
void | g_static_rec_mutex_lock_full ()
guint | g_static_rec_mutex_unlock_full ()
void | g_static_rec_mutex_free ()
void | g_static_rw_lock_init ()
void | g_static_rw_lock_reader_lock ()
gboolean | g_static_rw_lock_reader_trylock ()
void | g_static_rw_lock_reader_unlock ()
void | g_static_rw_lock_writer_lock ()
gboolean | g_static_rw_lock_writer_trylock ()
void | g_static_rw_lock_writer_unlock ()
void | g_static_rw_lock_free ()
void | g_static_private_init ()
gpointer | g_static_private_get ()
void | g_static_private_set ()
void | g_static_private_free ()

## Types and Values

#define | G_THREADS_IMPL_POSIX
#define | G_THREADS_IMPL_WIN32
enum | GThreadPriority
| GStaticMutex
#define | G_STATIC_MUTEX_INIT
struct | GStaticRecMutex
#define | G_STATIC_REC_MUTEX_INIT
struct | GStaticRWLock
#define | G_STATIC_RW_LOCK_INIT
struct | GStaticPrivate
#define | G_STATIC_PRIVATE_INIT

## Object Hierarchy

## Includes

    #include <glib.h>

## Description

These APIs are deprecated. You should not use them in new code. This section remains only to assist with understanding code that was written to use these APIs at some point in the past.

## Functions

### g_thread_init ()

    void
    g_thread_init (gpointer vtable);

`g_thread_init` has been deprecated since version 2.32 and should not be used in newly-written code.

This function is no longer necessary. The GLib threading system is automatically initialized at the start of your program.

If you use GLib from more than one thread, you must initialize the thread system by calling `g_thread_init()`.

Since version 2.24, calling `g_thread_init()` multiple times is allowed, but nothing happens except for the first call.

Since version 2.32, GLib does not support custom thread implementations anymore and the `vtable` parameter is ignored and you should pass `NULL`.

<note><para>`g_thread_init()` must not be called directly or indirectly in a callback from GLib. Also no mutexes may be currently locked while calling `g_thread_init()`.</para></note>

<note><para>To use `g_thread_init()` in your program, you have to link with the libraries that the command <command>pkg-config --libs gthread-2.0</command> outputs. This is not the case for all the other thread-related functions of GLib. Those can be used without having to link with the thread libraries.</para></note>

#### Parameters

vtable | a function table of type GThreadFunctions, that provides the entry points to the thread system to be used. Since 2.32, this parameter is ignored and should always be `NULL` |

### g_thread_supported ()

    gboolean
    g_thread_supported ();

`g_thread_supported` is deprecated and should not be used in newly-written code.

This macro returns `TRUE` if the thread system is initialized, and `FALSE` if it is not.

For language bindings, `g_thread_get_initialized()` provides the same functionality as a function.

#### Returns

`TRUE`, if the thread system is initialized

### g_thread_get_initialized ()

    gboolean
    g_thread_get_initialized (void);

`g_thread_get_initialized` is deprecated and should not be used in newly-written code.

Indicates if `g_thread_init()` has been called.

#### Returns

`TRUE` if threads have been initialized.

Since 2.20

### g_thread_create ()

    GThread *
    g_thread_create (GThreadFunc func,
                     gpointer data,
                     gboolean joinable,
                     GError **error);

`g_thread_create` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_thread_new()` instead

This function creates a new thread.

The new thread executes the function `func` with the argument `data` . If the thread was created successfully, it is returned.

`error` can be `NULL` to ignore errors, or non-`NULL` to report errors. The error is set, if and only if the function returns `NULL`.

This function returns a reference to the created thread only if `joinable` is `TRUE`. In that case, you must free this reference by calling `g_thread_unref()` or `g_thread_join()`. If `joinable` is `FALSE` then you should probably not touch the return value.

#### Parameters

func | a function to execute in the new thread |
data | an argument to supply to the new thread |
joinable | should this thread be joinable? |
error | return location for error, or `NULL` |

#### Returns

the new GThread on success

### g_thread_create_full ()

    GThread *
    g_thread_create_full (GThreadFunc func,
                          gpointer data,
                          gulong stack_size,
                          gboolean joinable,
                          gboolean bound,
                          GThreadPriority priority,
                          GError **error);

`g_thread_create_full` has been deprecated since version 2.32 and should not be used in newly-written code.

The `bound` and `priority` arguments are now ignored. Use `g_thread_new()`.

This function creates a new thread.

#### Parameters

func | a function to execute in the new thread. |
data | an argument to supply to the new thread. |
stack_size | a stack size for the new thread. |
joinable | should this thread be joinable? |
bound | ignored |
priority | ignored |
error | return location for error. |

#### Returns

the new GThread on success.

### g_thread_set_priority ()

    void
    g_thread_set_priority (GThread *thread,
                           GThreadPriority priority);

`g_thread_set_priority` has been deprecated since version 2.32 and should not be used in newly-written code.

Thread priorities no longer have any effect.

This function does nothing.

#### Parameters

thread | a GThread. |
priority | ignored |

### g_thread_foreach ()

    void
    g_thread_foreach (GFunc thread_func,
                      gpointer user_data);

`g_thread_foreach` has been deprecated since version 2.32 and should not be used in newly-written code.

There aren't many things you can do with a GThread, except comparing it with one that was returned from `g_thread_create()`. There are better ways to find out if your thread is still alive.

Call `thread_func` on all GThreads that have been created with `g_thread_create()`.

Note that threads may decide to exit while `thread_func` is running, so without intimate knowledge about the lifetime of foreign threads, `thread_func` shouldn't access the GThread* pointer passed in as first argument. However, `thread_func` will not be called for threads which are known to have exited already.

Due to thread lifetime checks, this function has an execution complexity which is quadratic in the number of existing threads.

#### Parameters

thread_func | function to call for all GThread structures |
user_data | second argument to `thread_func` |

Since 2.10

### g_mutex_new ()

    GMutex *
    g_mutex_new ();

`g_mutex_new` has been deprecated since version 2.32 and should not be used in newly-written code.

GMutex can now be statically allocated, or embedded in structures and initialised with `g_mutex_init()`.

Allocates and initializes a new GMutex.

#### Returns

a newly allocated GMutex. Use `g_mutex_free()` to free

### g_mutex_free ()

    void
    g_mutex_free (GMutex *mutex);

`g_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code.

GMutex can now be statically allocated, or embedded in structures and initialised with `g_mutex_init()`.

Destroys a `mutex` that has been created with `g_mutex_new()`.

Calling `g_mutex_free()` on a locked mutex may result in undefined behaviour.

#### Parameters

mutex | a GMutex |

### g_cond_new ()

    GCond*
    g_cond_new ();

`g_cond_new` has been deprecated since version 2.32 and should not be used in newly-written code.

GCond can now be statically allocated, or embedded in structures and initialised with `g_cond_init()`.

Allocates and initializes a new GCond.

#### Returns

a newly allocated GCond. Free with `g_cond_free()`

### g_cond_free ()

    void
    g_cond_free (GCond *cond);

`g_cond_free` has been deprecated since version 2.32 and should not be used in newly-written code.

GCond can now be statically allocated, or embedded in structures and initialised with `g_cond_init()`.

Destroys a GCond that has been created with `g_cond_new()`.

Calling `g_cond_free()` for a GCond on which threads are blocking leads to undefined behaviour.

#### Parameters

cond | a GCond |

### g_private_new ()

    GPrivate *
    g_private_new (GDestroyNotify notify);

`g_private_new` has been deprecated since version 2.32 and should not be used in newly-written code.

dynamic allocation of GPrivate is a bad idea. Use static storage and `G_PRIVATE_INIT()` instead.

Creates a new GPrivate.

#### Parameters

notify | a GDestroyNotify |

#### Returns

a newly allocated GPrivate (which can never be destroyed)

### g_static_mutex_init ()

    void
    g_static_mutex_init (GStaticMutex *mutex);

`g_static_mutex_init` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_mutex_init()`

Initializes `mutex` . Alternatively you can initialize it with G_STATIC_MUTEX_INIT.

#### Parameters

mutex | a GStaticMutex to be initialized. |

### g_static_mutex_lock ()

    void
    g_static_mutex_lock (GStaticMutex *mutex);

`g_static_mutex_lock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_mutex_lock()`

Works like `g_mutex_lock()`, but for a GStaticMutex.

#### Parameters

mutex | a GStaticMutex. |

### g_static_mutex_trylock ()

    gboolean
    g_static_mutex_trylock (GStaticMutex *mutex);

`g_static_mutex_trylock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_mutex_trylock()`

Works like `g_mutex_trylock()`, but for a GStaticMutex.

#### Parameters

mutex | a GStaticMutex. |

#### Returns

`TRUE`, if the GStaticMutex could be locked.

### g_static_mutex_unlock ()

    void
    g_static_mutex_unlock (GStaticMutex *mutex);

`g_static_mutex_unlock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_mutex_unlock()`

Works like `g_mutex_unlock()`, but for a GStaticMutex.

#### Parameters

mutex | a GStaticMutex. |

### g_static_mutex_get_mutex ()

    GMutex *
    g_static_mutex_get_mutex (GStaticMutex *mutex);

`g_static_mutex_get_mutex` has been deprecated since version 2.32 and should not be used in newly-written code.

Just use a GMutex

For some operations (like `g_cond_wait()`) you must have a GMutex instead of a GStaticMutex. This function will return the corresponding GMutex for `mutex` .

#### Parameters

mutex | a GStaticMutex. |

#### Returns

the GMutex corresponding to `mutex` .

### g_static_mutex_free ()

    void
    g_static_mutex_free (GStaticMutex *mutex);

`g_static_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_mutex_clear()`

Releases all resources allocated to `mutex` .

You don't have to call this functions for a GStaticMutex with an unbounded 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.

Calling `g_static_mutex_free()` on a locked mutex may result in undefined behaviour.

#### Parameters

mutex | a GStaticMutex to be freed. |

### g_static_rec_mutex_init ()

    void
    g_static_rec_mutex_init (GStaticRecMutex *mutex);

`g_static_rec_mutex_init` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_init()`

A GStaticRecMutex must be initialized with this function before it can be used. Alternatively you can initialize it with G_STATIC_REC_MUTEX_INIT.

#### Parameters

mutex | a GStaticRecMutex to be initialized. |

### g_static_rec_mutex_lock ()

    void
    g_static_rec_mutex_lock (GStaticRecMutex *mutex);

`g_static_rec_mutex_lock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_lock()`

Locks `mutex` . If `mutex` is already locked by another thread, the current thread will block until `mutex` is unlocked by the other thread. If `mutex` is already locked by the calling thread, this functions increases the depth of `mutex` and returns immediately.

#### Parameters

mutex | a GStaticRecMutex to lock. |

### g_static_rec_mutex_trylock ()

    gboolean
    g_static_rec_mutex_trylock (GStaticRecMutex *mutex);

`g_static_rec_mutex_trylock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_trylock()`

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, this functions increases the depth of `mutex` and immediately returns `TRUE`.

#### Parameters

mutex | a GStaticRecMutex to lock. |

#### Returns

`TRUE`, if `mutex` could be locked.

### g_static_rec_mutex_unlock ()

    void
    g_static_rec_mutex_unlock (GStaticRecMutex *mutex);

`g_static_rec_mutex_unlock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_unlock()`

Unlocks `mutex` . Another thread will be allowed to lock `mutex` only when it has been unlocked as many times as it had been locked before. If `mutex` is completely unlocked and another thread is blocked in a `g_static_rec_mutex_lock()` call for `mutex` , it will be woken and can lock `mutex` itself.

#### Parameters

mutex | a GStaticRecMutex to unlock. |

### g_static_rec_mutex_lock_full ()

    void
    g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
                                  guint depth);

`g_static_rec_mutex_lock_full` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_lock()`

Works like calling `g_static_rec_mutex_lock()` for `mutex` `depth` times.

#### Parameters

mutex | a GStaticRecMutex to lock. |
depth | number of times this mutex has to be unlocked to be completely unlocked. |

### g_static_rec_mutex_unlock_full ()

    guint
    g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);

`g_static_rec_mutex_unlock_full` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_unlock()`

Completely unlocks `mutex` . If another thread is blocked in a `g_static_rec_mutex_lock()` call for `mutex` , it will be woken and can lock `mutex` itself. This function returns the number of times that `mutex` has been locked by the current thread. To restore the state before the call to `g_static_rec_mutex_unlock_full()` you can call `g_static_rec_mutex_lock_full()` with the depth returned by this function.

#### Parameters

mutex | a GStaticRecMutex to completely unlock. |

#### Returns

number of times `mutex` has been locked by the current thread.

### g_static_rec_mutex_free ()

    void
    g_static_rec_mutex_free (GStaticRecMutex *mutex);

`g_static_rec_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rec_mutex_clear()`

Releases all resources allocated to a GStaticRecMutex.

You don't have to call this functions for a GStaticRecMutex with an unbounded lifetime, i.e. objects declared 'static', but if you have a GStaticRecMutex as a member of a structure and the structure is freed, you should also free the GStaticRecMutex.

#### Parameters

mutex | a GStaticRecMutex to be freed. |

### g_static_rw_lock_init ()

    void
    g_static_rw_lock_init (GStaticRWLock *lock);

`g_static_rw_lock_init` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rw_lock_init()` instead

A GStaticRWLock must be initialized with this function before it can be used. Alternatively you can initialize it with G_STATIC_RW_LOCK_INIT.

#### Parameters

lock | a GStaticRWLock to be initialized. |

### g_static_rw_lock_reader_lock ()

    void
    g_static_rw_lock_reader_lock (GStaticRWLock *lock);

`g_static_rw_lock_reader_lock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use `g_rw_lock_reader_lock()` instead

Locks `lock` for reading. There may be unlimited concurrent locks for reading of a GStaticRWLock at the same time. If `lock` is already locked for writing by another thread or if another thread is already waiting to lock `lock` for writing, this function will block until `lock` is unlocked by the other writing thread and no other writing threads want to lock `lock` . This lock has to be unlocked by `g_static_rw_lock_reader_unlock()`.

GStaticRWLock is not recursive. It might seem to be possible to recursively lock for reading, but that can result in a deadlock, due to writer preference.

#### Parameters

lock | a GStaticRWLock to lock for reading. |

### g_static_rw_lock_reader_trylock ()

    gboolean
    g_static_rw_lock_reader_trylock (GStaticRWLock *lock);

`g_static_rw_lock_reader_trylock` is deprecated and should not be used in newly-written code.

Tries to lock `lock` for reading. If `lock` is already locked for writing by another thread or if another thread is already waiting to lock `lock` for writing, immediately returns `FALSE`. Otherwise locks `lock` for reading and returns `TRUE`. This lock has to be unlocked by `g_static_rw_lock_reader_unlock()`.

#### Parameters

lock | a GStaticRWLock to lock for reading |

#### Returns

`TRUE`, if `lock` could be locked for reading

Deprectated: 2.32: Use `g_rw_lock_reader_trylock()` instead

### g_static_rw_lock_reader_unlock ()

    void
    g_static_rw_lock_reader_unlock (GStaticRWLock *lock);

`g_static_rw_lock_reader_unlock` is deprecated and should not be used in newly-written code.

Unlocks `lock` . If a thread waits to lock `lock` for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock `lock` for writing.

Deprectated: 2.32: Use `g_rw_lock_reader_unlock()` instead

#### Parameters

lock | a GStaticRWLock to unlock after reading |

### g_static_rw_lock_writer_lock ()

    void
    g_static_rw_lock_writer_lock (GStaticRWLock *lock);

`g_static_rw_lock_writer_lock` is deprecated and should not be used in newly-written code.

Locks `lock` for writing. If `lock` is already locked for writing or reading by other threads, this function will block until `lock` is completely unlocked and then lock `lock` for writing. While this functions waits to lock `lock` , no other thread can lock `lock` for reading. When `lock` is locked for writing, no other thread can lock `lock` (neither for reading nor writing). This lock has to be unlocked by `g_static_rw_lock_writer_unlock()`.

Deprectated: 2.32: Use `g_rw_lock_writer_lock()` instead

#### Parameters

lock | a GStaticRWLock to lock for writing |

### g_static_rw_lock_writer_trylock ()

    gboolean
    g_static_rw_lock_writer_trylock (GStaticRWLock *lock);

`g_static_rw_lock_writer_trylock` is deprecated and should not be used in newly-written code.

Tries to lock `lock` for writing. If `lock` is already locked (for either reading or writing) by another thread, it immediately returns `FALSE`. Otherwise it locks `lock` for writing and returns `TRUE`. This lock has to be unlocked by `g_static_rw_lock_writer_unlock()`.

#### Parameters

lock | a GStaticRWLock to lock for writing |

#### Returns

`TRUE`, if `lock` could be locked for writing

Deprectated: 2.32: Use `g_rw_lock_writer_trylock()` instead

### g_static_rw_lock_writer_unlock ()

    void
    g_static_rw_lock_writer_unlock (GStaticRWLock *lock);

`g_static_rw_lock_writer_unlock` is deprecated and should not be used in newly-written code.

Unlocks `lock` . If a thread is waiting to lock `lock` for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock `lock` for writing. If no thread is waiting to lock `lock` for writing, and some thread or threads are waiting to lock `lock` for reading, the waiting threads are woken up and can lock `lock` for reading.

Deprectated: 2.32: Use `g_rw_lock_writer_unlock()` instead

#### Parameters

lock | a GStaticRWLock to unlock after writing. |

### g_static_rw_lock_free ()

    void
    g_static_rw_lock_free (GStaticRWLock *lock);

`g_static_rw_lock_free` has been deprecated since version 2.32 and should not be used in newly-written code.

Use a GRWLock instead

Releases all resources allocated to `lock` .

You don't have to call this functions for a GStaticRWLock with an unbounded 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.

#### Parameters

lock | a GStaticRWLock to be freed. |

### g_static_private_init ()

    void
    g_static_private_init (GStaticPrivate *private_key);

`g_static_private_init` is deprecated and should not be used in newly-written code.

Initializes `private_key` . Alternatively you can initialize it with G_STATIC_PRIVATE_INIT.

#### Parameters

private_key | a GStaticPrivate to be initialized |

### g_static_private_get ()

    gpointer
    g_static_private_get (GStaticPrivate *private_key);

`g_static_private_get` is deprecated and should not be used in newly-written code.

Works like `g_private_get()` only for a GStaticPrivate.

This function works even if `g_thread_init()` has not yet been called.

#### Parameters

private_key | a GStaticPrivate |

#### Returns

the corresponding pointer

### g_static_private_set ()

    void
    g_static_private_set (GStaticPrivate *private_key,
                          gpointer data,
                          GDestroyNotify notify);

`g_static_private_set` is deprecated and should not be used in newly-written code.

Sets the pointer keyed to `private_key` for the current thread and the function `notify` to be called with that pointer (`NULL` or non-`NULL`), whenever the pointer is set again or whenever the current thread ends.

This function works even if `g_thread_init()` has not yet been called. 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 that called `g_thread_init()`.

`notify` is used quite differently from `destructor` in `g_private_new()`.

#### Parameters

private_key | a GStaticPrivate |
data | the new pointer |
notify | a function to be called with the pointer whenever the current thread ends or sets this pointer again |

### g_static_private_free ()

    void
    g_static_private_free (GStaticPrivate *private_key);

`g_static_private_free` is deprecated and should not be used in newly-written code.

Releases all resources allocated to `private_key` .

You don't have to call this functions for a GStaticPrivate with an unbounded 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.

#### Parameters

private_key | a GStaticPrivate to be freed |

## Types and Values

### G_THREADS_IMPL_POSIX

    #define G_THREADS_IMPL_POSIX

`G_THREADS_IMPL_POSIX` has been deprecated since version 2.32 and should not be used in newly-written code.

POSIX threads are in use on all non-Windows systems. Use G_OS_WIN32 to detect Windows.

This macro is defined if POSIX style threads are used.

### G_THREADS_IMPL_WIN32

    #define G_THREADS_IMPL_NONE

`G_THREADS_IMPL_WIN32` has been deprecated since version 2.32 and should not be used in newly-written code.

Use G_OS_WIN32 to detect Windows.

This macro is defined if Windows style threads are used.

### enum GThreadPriority

`GThreadPriority` has been deprecated since version 2.32 and should not be used in newly-written code.

Thread priorities no longer have any effect.

#### Members

G_THREAD_PRIORITY_LOW | a priority lower than normal |
G_THREAD_PRIORITY_NORMAL | the default priority |
G_THREAD_PRIORITY_HIGH | a priority higher than normal |
G_THREAD_PRIORITY_URGENT | the highest priority |

### GStaticMutex

    typedef struct _GStaticMutex GStaticMutex;

A GStaticMutex works like a GMutex.

Prior to GLib 2.32, GStaticMutex had the significant advantage that it doesn't need to be created at run-time, but can be defined at compile-time. Since 2.32, GMutex can be statically allocated as well, and GStaticMutex has been deprecated.

Here is a version of our `give_me_next_number()` example using a GStaticMutex:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int
    give_me_next_number (void)
    {
      static int current_number = 0;
      int ret_val;
      static GStaticMutex mutex = G_STATIC_MUTEX_INIT;

      g_static_mutex_lock (&mutex);
      ret_val = current_number = calc_next_number (current_number);
      g_static_mutex_unlock (&mutex);

      return ret_val;
    }

Sometimes you would like to dynamically create a mutex. If you don't want to require prior calling to `g_thread_init()`, because your code should also be usable in non-threaded programs, you are not able to use `g_mutex_new()` and thus GMutex, as that requires a prior call to `g_thread_init()`. In theses cases you can also use a GStaticMutex. It must be initialized with `g_static_mutex_init()` before using it and freed with with `g_static_mutex_free()` when not needed anymore to free up any allocated resources.

Even though GStaticMutex is not opaque, it should only be used with the following functions, as it is defined differently on different platforms.

All of the g_static_mutex_* functions apart from `g_static_mutex_get_mutex()` can also be used even if `g_thread_init()` has not yet been called. Then they do nothing, apart from `g_static_mutex_trylock()` which does nothing but returning `TRUE`.

All of the g_static_mutex_* functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.

### G_STATIC_MUTEX_INIT

    #define G_STATIC_MUTEX_INIT

`G_STATIC_MUTEX_INIT` is deprecated and should not be used in newly-written code.

A GStaticMutex must be initialized with this macro, before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_mutex_init()`.

    1
    GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;

### struct GStaticRecMutex

    struct GStaticRecMutex {
    };

`GStaticRecMutex` is deprecated and should not be used in newly-written code.

A GStaticRecMutex works like a GStaticMutex, but it can be locked multiple times by one thread. If you enter it n times, you have to unlock it n times again to let other threads lock it. An exception is the function `g_static_rec_mutex_unlock_full()`: that allows you to unlock a GStaticRecMutex completely returning the depth, (i.e. the number of times this mutex was locked). The depth can later be used to restore the state of the GStaticRecMutex by calling `g_static_rec_mutex_lock_full()`. In GLib 2.32, GStaticRecMutex has been deprecated in favor of GRecMutex.

Even though GStaticRecMutex is not opaque, it should only be used with the following functions.

All of the g_static_rec_mutex_* functions can be used even if `g_thread_init()` has not been called. Then they do nothing, apart from `g_static_rec_mutex_trylock()`, which does nothing but returning `TRUE`.

### G_STATIC_REC_MUTEX_INIT

    #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }

`G_STATIC_REC_MUTEX_INIT` is deprecated and should not be used in newly-written code.

A GStaticRecMutex must be initialized with this macro before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_rec_mutex_init()`.

    1
    GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;

### struct GStaticRWLock

    struct GStaticRWLock {
    };

`GStaticRWLock` has been deprecated since version 2.32 and should not be used in newly-written code.

Use a GRWLock instead

The GStaticRWLock struct represents a read-write lock. A read-write lock can be used for protecting data that some portions of code only read from, while others also write. In such situations it is desirable that several readers can read at once, whereas of course only one writer may write at a time.

Take a look at the following example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    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 (&rwlock);
      if (index < array->len)
        retval = g_ptr_array_index (array, index);
      g_static_rw_lock_reader_unlock (&rwlock);

      return retval;
    }

    void
    my_array_set (guint index, gpointer data)
    {
      g_static_rw_lock_writer_lock (&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 (&rwlock);
    }

This example shows an array which can be accessed by many readers (the `my_array_get()` function) simultaneously, whereas the writers (the `my_array_set()` function) will only be allowed once at 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.

Most of the time, writers should have precedence over readers. That means, for this implementation, that as soon as a writer wants to lock the data, no other reader is allowed to lock the data, whereas, of course, the readers that already have locked the data are allowed to finish their operation. As soon as the last reader unlocks the data, the writer will lock it.

Even though GStaticRWLock is not opaque, it should only be used with the following functions.

All of the g_static_rw_lock_* functions can be used even if `g_thread_init()` has not been called. Then they do nothing, apart from g_static_rw_lock_*_trylock, which does nothing but returning `TRUE`.

A read-write lock has a higher overhead than a mutex. For example, both `g_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 the time to lock and unlock a GStaticRWLock that it does to lock and unlock a GStaticMutex. So only data structures that are accessed by multiple readers, and which keep the lock for a considerable time justify a GStaticRWLock. The above example most probably would fare better with a GStaticMutex.

### G_STATIC_RW_LOCK_INIT

    #define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }

`G_STATIC_RW_LOCK_INIT` is deprecated and should not be used in newly-written code.

A GStaticRWLock must be initialized with this macro before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_rw_lock_init()`.

    1
    GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;

### struct GStaticPrivate

    struct GStaticPrivate {
    };

`GStaticPrivate` is deprecated and should not be used in newly-written code.

A GStaticPrivate works almost like a GPrivate, but it has one significant advantage. It doesn't need to be created at run-time like a GPrivate, but can be defined at compile-time. This is similar to the difference between GMutex and GStaticMutex.

Now look at our `give_me_next_number()` example with GStaticPrivate:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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;
    }

### G_STATIC_PRIVATE_INIT

    #define G_STATIC_PRIVATE_INIT

`G_STATIC_PRIVATE_INIT` is deprecated and should not be used in newly-written code.

Every GStaticPrivate must be initialized with this macro, before it can be used.

    1
    GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;

## See Also

GThread