Top |
#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 |
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.
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>
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 |
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.
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.
Since: 2.20
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.
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 |
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.
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.
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.
thread_func |
function to call for all GThread structures |
|
user_data |
second argument to |
Since: 2.10
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.
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.
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.
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.
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.
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
.
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.
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.
Works like g_mutex_trylock()
, but for a GStaticMutex.
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.
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
.
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.
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.
A GStaticRecMutex must be initialized with this function before it
can be used. Alternatively you can initialize it with
G_STATIC_REC_MUTEX_INIT
.
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.
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.
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.
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
.
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.
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.
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.
Works like calling g_static_rec_mutex_lock()
for mutex
depth
times.
mutex |
a GStaticRecMutex to lock. |
|
depth |
number of times this mutex has to be unlocked to be completely unlocked. |
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.
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.
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.
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.
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
.
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.
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()
.
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.
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()
.
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()
.
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.
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.
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
.
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.
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()
.
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.
#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.
#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.
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.
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.
#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 { };
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
.
#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 { };
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.
#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 { };
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 (¤t_number_key); if (!current_number) { current_number = g_new (int, 1); *current_number = 0; g_static_private_set (¤t_number_key, current_number, g_free); } *current_number = calc_next_number (*current_number); return *current_number; } |
#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; |