1
<!-- ##### SECTION Title ##### -->
4
<!-- ##### SECTION Short_Description ##### -->
5
Functions for using GDK in multi-threaded programs
7
<!-- ##### SECTION Long_Description ##### -->
9
For thread safety, GDK relies on the thread primitives in GLib,
10
and on the thread-safe GLib main loop.
13
GLib is completely thread safe (all global data is automatically
14
locked), but individual data structure instances are not automatically
15
locked for performance reasons. So e.g. you must coordinate
16
accesses to the same #GHashTable from multiple threads.
19
GTK+ is "thread aware" but not thread safe — it provides a
20
global lock controlled by gdk_threads_enter()/gdk_threads_leave()
21
which protects all use of GTK+. That is, only one thread can use GTK+
25
Unfortunately the above holds with the X11 backend only. With the
26
Win32 backend, GDK calls should not be attempted from multiple threads
30
You must call g_thread_init() and gdk_threads_init() before executing
31
any other GTK+ or GDK functions in a threaded GTK+ program.
34
Idles, timeouts, and input functions are executed outside
35
of the main GTK+ lock. So, if you need to call GTK+
36
inside of such a callback, you must surround the callback
37
with a gdk_threads_enter()/gdk_threads_leave() pair.
38
(However, signals are still executed within the main
42
In particular, this means, if you are writing widgets that might
43
be used in threaded programs, you <emphasis>must</emphasis> surround
44
timeouts and idle functions in this matter.
47
As always, you must also surround any calls to GTK+ not made within
48
a signal handler with a gdk_threads_enter()/gdk_threads_leave() pair.
52
Before calling gdk_threads_leave() from a thread other
53
than your main thread, you probably want to call gdk_flush()
54
to send all pending commands to the windowing system.
55
(The reason you don't need to do this from the main thread
56
is that GDK always automatically flushes pending commands
57
when it runs out of incoming events to process and has
58
to sleep while waiting for more events.)
61
<para>A minimal main program for a threaded GTK+ application
65
<programlisting role="C">
67
main (int argc, char *argv[])
72
gdk_threads_init (<!-- -->);
73
gdk_threads_enter (<!-- -->);
75
gtk_init (&argc, &argv);
77
window = create_window (<!-- -->);
78
gtk_widget_show (window);
81
gdk_threads_leave (<!-- -->);
89
Callbacks require a bit of attention. Callbacks from GTK+ signals
90
are made within the GTK+ lock. However callbacks from GLib (timeouts,
91
IO callbacks, and idle functions) are made outside of the GTK+
92
lock. So, within a signal handler you do not need to call
93
gdk_threads_enter(), but within the other types of callbacks, you
97
<para>Erik Mouw contributed the following code example to
98
illustrate how to use threads within GTK+ programs.
102
<programlisting role="C">
103
/*-------------------------------------------------------------------------
104
* Filename: gtk-thread.c
106
* Copyright: Copyright (C) 1999, Erik Mouw
107
* Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
108
* Description: GTK threads example.
109
* Created at: Sun Oct 17 21:27:09 1999
110
* Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
111
* Modified at: Sun Oct 24 17:21:41 1999
112
*-----------------------------------------------------------------------*/
116
* cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
118
* Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
123
#include <stdio.h>
124
#include <stdlib.h>
125
#include <unistd.h>
126
#include <time.h>
127
#include <gtk/gtk.h>
128
#include <glib.h>
129
#include <pthread.h>
131
#define YES_IT_IS (1)
132
#define NO_IT_IS_NOT (0)
140
G_LOCK_DEFINE_STATIC (yes_or_no);
141
static volatile int yes_or_no = YES_IT_IS;
143
void destroy (GtkWidget *widget, gpointer data)
145
gtk_main_quit (<!-- -->);
148
void *argument_thread (void *args)
150
yes_or_no_args *data = (yes_or_no_args *)args;
151
gboolean say_something;
156
sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
158
/* lock the yes_or_no_variable */
161
/* do we have to say something? */
162
say_something = (yes_or_no != data->what);
166
/* set the variable */
167
yes_or_no = data->what;
170
/* Unlock the yes_or_no variable */
171
G_UNLOCK (yes_or_no);
175
/* get GTK thread lock */
176
gdk_threads_enter (<!-- -->);
179
if(data->what == YES_IT_IS)
180
gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
182
gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
184
/* release GTK thread lock */
185
gdk_threads_leave (<!-- -->);
192
int main (int argc, char *argv[])
196
yes_or_no_args yes_args, no_args;
197
pthread_t no_tid, yes_tid;
200
g_thread_init (NULL);
201
gdk_threads_init (<!-- -->);
202
gdk_threads_enter (<!-- -->);
205
gtk_init(&argc, &argv);
207
/* init random number generator */
208
srand ((unsigned int) time (NULL));
210
/* create a window */
211
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
213
gtk_signal_connect (GTK_OBJECT (window), "destroy",
214
GTK_SIGNAL_FUNC (destroy), NULL);
216
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
219
label = gtk_label_new ("And now for something completely different ...");
220
gtk_container_add (GTK_CONTAINER (window), label);
222
/* show everything */
223
gtk_widget_show (label);
224
gtk_widget_show (window);
226
/* create the threads */
227
yes_args.label = label;
228
yes_args.what = YES_IT_IS;
229
pthread_create (&yes_tid, NULL, argument_thread, &yes_args);
231
no_args.label = label;
232
no_args.what = NO_IT_IS_NOT;
233
pthread_create (&no_tid, NULL, argument_thread, &no_args);
235
/* enter the GTK main loop */
237
gdk_threads_leave (<!-- -->);
244
<!-- ##### SECTION See_Also ##### -->
249
<!-- ##### SECTION Stability_Level ##### -->
252
<!-- ##### MACRO GDK_THREADS_ENTER ##### -->
254
This macro marks the beginning of a critical section in which GDK and GTK+
255
functions can be called. Only one thread at a time can be in such a
256
critial section. The macro expands to a no-op if #G_THREADS_ENABLED
257
has not been defined. Typically gdk_threads_enter() should be used
258
instead of this macro.
263
<!-- ##### MACRO GDK_THREADS_LEAVE ##### -->
265
This macro marks the end of a critical section
266
begun with #GDK_THREADS_ENTER.
271
<!-- ##### FUNCTION gdk_threads_init ##### -->
278
<!-- ##### FUNCTION gdk_threads_enter ##### -->
280
This macro marks the beginning of a critical section
281
in which GDK and GTK+ functions can be called.
282
Only one thread at a time can be in such a critial
288
<!-- ##### FUNCTION gdk_threads_leave ##### -->
290
Leaves a critical region begun with gdk_threads_enter().
295
<!-- ##### VARIABLE gdk_threads_mutex ##### -->
297
The #GMutex used to implement the critical region for
298
gdk_threads_enter()/gdk_threads_leave().
302
<!-- ##### FUNCTION gdk_threads_set_lock_functions ##### -->