Deprecated thread API

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

Functions

Types and Values

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 ();

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 has been deprecated since version 2.32 and should not be used in newly-written code.

Use g_rw_lock_reader_trylock() instead

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


g_static_rw_lock_reader_unlock ()

void
g_static_rw_lock_reader_unlock (GStaticRWLock *lock);

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

Use g_rw_lock_reader_unlock() instead

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.

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 has been deprecated since version 2.32 and should not be used in newly-written code.

Use g_rw_lock_writer_lock() instead

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().

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 has been deprecated since version 2.32 and should not be used in newly-written code.

Use g_rw_lock_writer_trylock() instead

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


g_static_rw_lock_writer_unlock ()

void
g_static_rw_lock_writer_unlock (GStaticRWLock *lock);

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

Use g_rw_lock_writer_unlock() instead

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.

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.

Thread priorities.

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 these 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

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, 0, { 0 } } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_rec_mutex_init)

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 } GLIB_DEPRECATED_MACRO_IN_2_32_FOR(g_rw_lock_init)

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

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

1
GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;

See Also

GThread