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 You must call g_thread_init() and gdk_threads_init() before executing
26 any other GTK+ or GDK functions in a threaded GTK+ program.
29 Idles, timeouts, and input functions are executed outside
30 of the main GTK+ lock. So, if you need to call GTK+
31 inside of such a callback, you must surround the callback
32 with a gdk_threads_enter()/gdk_threads_leave() pair.
33 (However, signals are still executed within the main
37 In particular, this means, if you are writing widgets that might
38 be used in threaded programs, you <emphasis>must</emphasis> surround
39 timeouts and idle functions in this matter.
42 As always, you must also surround any calls to GTK+ not made within
43 a signal handler with a gdk_threads_enter()/gdk_threads_leave() pair.
47 Before calling gdk_threads_leave() from a thread other
48 than your main thread, you probably want to call gdk_flush()
49 to send all pending commands to the windowing system.
50 (The reason you don't need to do this from the main thread
51 is that GDK always automatically flushes pending commands
52 when it runs out of incoming events to process and has
53 to sleep while waiting for more events.)
56 <para>A minimal main program for a threaded GTK+ application
60 <programlisting role="C">
62 main (int argc, char *argv[])
67 gdk_threads_init (<!-- -->);
68 gdk_threads_enter (<!-- -->);
70 gtk_init (&argc, &argv);
72 window = create_window (<!-- -->);
73 gtk_widget_show (window);
76 gdk_threads_leave (<!-- -->);
84 Callbacks require a bit of attention. Callbacks from GTK+ signals
85 are made within the GTK+ lock. However callbacks from GLib (timeouts,
86 IO callbacks, and idle functions) are made outside of the GTK+
87 lock. So, within a signal handler you do not need to call
88 gdk_threads_enter(), but within the other types of callbacks, you
92 <para>Erik Mouw contributed the following code example to
93 illustrate how to use threads within GTK+ programs.
97 <programlisting role="C">
98 /*-------------------------------------------------------------------------
99 * Filename: gtk-thread.c
101 * Copyright: Copyright (C) 1999, Erik Mouw
102 * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
103 * Description: GTK threads example.
104 * Created at: Sun Oct 17 21:27:09 1999
105 * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
106 * Modified at: Sun Oct 24 17:21:41 1999
107 *-----------------------------------------------------------------------*/
111 * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
113 * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
118 #include <stdio.h>
119 #include <stdlib.h>
120 #include <unistd.h>
121 #include <time.h>
122 #include <gtk/gtk.h>
123 #include <glib.h>
124 #include <pthread.h>
126 #define YES_IT_IS (1)
127 #define NO_IT_IS_NOT (0)
135 G_LOCK_DEFINE_STATIC (yes_or_no);
136 static volatile int yes_or_no = YES_IT_IS;
138 void destroy (GtkWidget *widget, gpointer data)
140 gtk_main_quit (<!-- -->);
143 void *argument_thread (void *args)
145 yes_or_no_args *data = (yes_or_no_args *)args;
146 gboolean say_something;
151 sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
153 /* lock the yes_or_no_variable */
156 /* do we have to say something? */
157 say_something = (yes_or_no != data->what);
161 /* set the variable */
162 yes_or_no = data->what;
165 /* Unlock the yes_or_no variable */
166 G_UNLOCK (yes_or_no);
170 /* get GTK thread lock */
171 gdk_threads_enter (<!-- -->);
174 if(data->what == YES_IT_IS)
175 gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
177 gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
179 /* release GTK thread lock */
180 gdk_threads_leave (<!-- -->);
187 int main (int argc, char *argv[])
191 yes_or_no_args yes_args, no_args;
192 pthread_t no_tid, yes_tid;
195 g_thread_init (NULL);
196 gdk_threads_init (<!-- -->);
197 gdk_threads_enter (<!-- -->);
200 gtk_init(&argc, &argv);
202 /* init random number generator */
203 srand ((unsigned int) time (NULL));
205 /* create a window */
206 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
208 gtk_signal_connect (GTK_OBJECT (window), "destroy",
209 GTK_SIGNAL_FUNC (destroy), NULL);
211 gtk_container_set_border_width (GTK_CONTAINER (window), 10);
214 label = gtk_label_new ("And now for something completely different ...");
215 gtk_container_add (GTK_CONTAINER (window), label);
217 /* show everything */
218 gtk_widget_show (label);
219 gtk_widget_show (window);
221 /* create the threads */
222 yes_args.label = label;
223 yes_args.what = YES_IT_IS;
224 pthread_create (&yes_tid, NULL, argument_thread, &yes_args);
226 no_args.label = label;
227 no_args.what = NO_IT_IS_NOT;
228 pthread_create (&no_tid, NULL, argument_thread, &no_args);
230 /* enter the GTK main loop */
232 gdk_threads_leave (<!-- -->);
239 <!-- ##### SECTION See_Also ##### -->
244 <!-- ##### SECTION Stability_Level ##### -->
247 <!-- ##### MACRO GDK_THREADS_ENTER ##### -->
249 This macro marks the beginning of a critical section in which GDK and GTK+
250 functions can be called. Only one thread at a time can be in such a
251 critial section. The macro expands to a no-op if #G_THREADS_ENABLED
252 has not been defined. Typically gdk_threads_enter() should be used
253 instead of this macro.
258 <!-- ##### MACRO GDK_THREADS_LEAVE ##### -->
260 This macro marks the end of a critical section
261 begun with #GDK_THREADS_ENTER.
266 <!-- ##### FUNCTION gdk_threads_init ##### -->
273 <!-- ##### FUNCTION gdk_threads_enter ##### -->
275 This macro marks the beginning of a critical section
276 in which GDK and GTK+ functions can be called.
277 Only one thread at a time can be in such a critial
283 <!-- ##### FUNCTION gdk_threads_leave ##### -->
285 Leaves a critical region begun with gdk_threads_enter().
290 <!-- ##### VARIABLE gdk_threads_mutex ##### -->
292 The #GMutex used to implement the critical region for
293 gdk_threads_enter()/gdk_threads_leave(). This variable should not be
294 used directly — consider it private.
298 <!-- ##### FUNCTION gdk_threads_set_lock_functions ##### -->