Shoal Research

for ideas and innovations

  • Increase font size
  • Default font size
  • Decrease font size
Home Computing Linux GTK+ Threading

GTK+ Threading

E-mail Print PDF

I've just been working with  GTK+, a GUI toolkit for C/Linux - but ported to pretty much everything.  Initial impressions are quite good, although I am starting to miss Qt/Creator   Anyhow, I hit the age-old problem quite quickly.  The GUI thread just isn''t enough.  To start with, I just slapped in a ''normal'' thread (pthread_t) but when the time came to update the GUI, things started to go pete tong.  Here is how I sorted it;

 

 

GTK+ is described as ''thread aware'' rather than ''thread safe'' so you need to be a bit careful, although after a little investigation it gets very simple.

Firstly, let GLib/GTK know that it may need to share (these should be done FIRST and in this order before any other GLib code gets run);

1
2
g_thread_init(NULL);
gdk_threads_init();

 

Then you can start a thread;

1
2
GError *gError = NULL;
g_thread_create(my_thread, pMyData, FALSE, &Error);

 

The prototype of the thread function you want to call should look something like this;

1
void *my_thread(void *ptr);

 

Finally all critical code should be wrapped in;

1
gdk_threads_enter();

and

1
gdk_threads_leave();

INCLUDING gtk_main();

These functions are basically mutex macros which stop two threads accessing the same data at the same time.

 

Compile in the same way as any other GTK+ program, but ensure the following is added to the compiler options;

1
-lgthread-2.0

 

 

Here is a very simple example for clarification;

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <gtk/gtk.h>
 
/ Label that we will change the text of
GtkWidget *label;
 
// The thread.
void *my_thread(void *pData)
{
  gdk_threads_enter();
  gtk_label_set_text(GTK_LABEL(label), "Not My Label");
  gdk_threads_leave();
 
  return 0;
}
 
int main(int argc, char *argv[])
{
  // Thread safe
  g_thread_init(NULL);
  gdk_threads_init();
 
  // Load GUI.
  gtk_init (&argc, &argv);
  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
  // Simple label
  label = gtk_label_new("My Label");
  gtk_container_add(GTK_CONTAINER(window), label);
  gtk_widget_show(label);
  gtk_widget_show(window);
 
  // Load the thread.
  GError *error = NULL;
  void *pData = 0x00;
  if (!g_thread_create(my_thread, pData, FALSE, &error))
  {
    g_printerr ("Failed to create thread: %sn", error->message);
    return 1;
  }
 
  // Run window.
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();
 
  return 0;
}

 

It can be compiled using the following;

1
gcc -Wall -g shoal_test.c `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` -lgthread-2.0

 

 

Its as simple as that.  I hope it helps someone!

Last Updated on Friday, 02 January 2004 12:32  

Add your comment

Your name:
Your email:
Your website:
Subject:
Comment:

Anti-spam: complete the task