GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sat Dec 20, 2014 11:01 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: The good way to manage threads for portable gtk app
PostPosted: Wed Oct 17, 2012 12:38 pm 
Offline
Familiar Face

Joined: Wed Oct 17, 2012 12:23 pm
Posts: 5
Hi all,

I'm sorry, I guess the question has already been asked, but I can't get any good and working answer regarding this subject.

I've read that gtk functions must only be called within the main thread, otherwise you must "lock" thanks to gdk_threads_enter() and gdk_threads_leave() functions.
I've read that all gtk callbacks are called within the main thread.

Because I have some functions that are sometimes called from callbacks (so the main thread), and sometimes called from other threads, so sometimes I need to lock the thread, and sometimes not..

To solve this, I just created a new thread from within callbacks, but it's still not working properly and does not have the same behaviour on Linux and Windows.

For every callbacks, this is what I tried :

Code:
gboolean my_callback(widget*, gpointer)
{
  g_thread_create(my_thread, ...);
}


void my_thread(...)
{
  gdk_threads_enter();
  /* call to gdk functions */
  gdk_threads_leave();
}

But I still get some application locks (windows are freezing) ...

Any help ? Any tutorial for the REAL and PORTABLE way to work with gtk threads ?

Thanks for help. Best regards, Vincent.


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Thu Oct 18, 2012 7:35 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello and welcome to the GTK+ forums!

The right way of using GTK+ is from single thread only. Anything that manipulates your GUI should be done in main thread (more precisely, in the thread that is running main loop). If you need to perform something that will take enough time to freeze the user interface, you should spawn new or reuse existing thread to do the calculation and then schedule GUI update by adding idle source to main loop.

In the past, developers of GTK+ included locking mechanism that made it possible to use GTK+ from multiple threads, but that stuff was never really 100% safe if you wanted your application to run on more than one supported platform.

To give you an idea of how to structure you application, I created this simple demo:
Code:
#include <gtk/gtk.h>

static gboolean
update_entry (GtkEntry *entry)
{
  gtk_entry_progress_pulse (entry);

  return FALSE;
}

static gboolean
terminate (GThread *thread)
{
  g_thread_join (thread);

  return FALSE;
}

static void *
thread_func (GtkEntry *entry)
{
  int i;

  for (i = 0; i < 100; i++)
    {
      usleep (100000); /* 0.1 s */
      gdk_threads_add_idle ((GSourceFunc)update_entry, entry);
    }

  /* Make sure this thread is joined properly */
  gdk_threads_add_idle ((GSourceFunc)terminate, g_thread_self ());
  return NULL;
}

int
main (int    argc,
      char **argv)
{
  GtkWidget *window,
            *entry;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW (window), 200, -1);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  entry = gtk_entry_new ();
  gtk_container_add (GTK_CONTAINER (window), entry);

  gtk_widget_show_all (window);

  /* Start thread */
  g_thread_new ("dummy", (GThreadFunc)thread_func, entry);

  gtk_main ();

  return 0;
}


Cheers,
Tadej


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Fri Oct 19, 2012 1:44 pm 
Offline
Familiar Face

Joined: Wed Oct 17, 2012 12:23 pm
Posts: 5
Hi tadeboro,

Thanks for your reply.

There's just 1 point I don't understand..

Why does the thread need to join itself ?
What does this mean ??


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Fri Oct 19, 2012 3:53 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hi.

When joining thread, you can get the return value of threaded function. g_thread_join() will also block until the thread finishes, so you can use it as a synchronization in your application.

In sample app I demonstrated, I used it to free the GThread structure (avoid memory leak). But this is not the only way. Code below is functionally equivalent to what I posted last time, but has no way of retrieving return value of threaded function.

Code:
#include <gtk/gtk.h>

static gboolean
update_entry (GtkEntry *entry)
{
  gtk_entry_progress_pulse (entry);

  return FALSE;
}

static void *
thread_func (GtkEntry *entry)
{
  int i;

  for (i = 0; i < 100; i++)
    {
      usleep (100000); /* 0.1 s */
      gdk_threads_add_idle ((GSourceFunc)update_entry, entry);
    }

  return NULL;
}

int
main (int    argc,
      char **argv)
{
  GtkWidget *window,
            *entry;
  GThread *thread;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW (window), 200, -1);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  entry = gtk_entry_new ();
  gtk_container_add (GTK_CONTAINER (window), entry);

  gtk_widget_show_all (window);

  /* Start thread */
  thread = g_thread_new ("dummy", (GThreadFunc)thread_func, entry);
  g_thread_unref (thread);

  gtk_main ();

  return 0;
}


Cheers,
Tadej


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Sun Oct 28, 2012 9:20 am 
Offline
Familiar Face

Joined: Wed Oct 17, 2012 12:23 pm
Posts: 5
I got it ..

Thanks for your help !

Best regards,
Vincent.


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Sun Oct 28, 2012 9:43 am 
Offline
Familiar Face

Joined: Wed Oct 17, 2012 12:23 pm
Posts: 5
One more thing ..

I have troubles with memory leak.

I have a g_thread, that does this in a loop :
Code:
gdk_threads_add_idle((GSourceFunc)upgrade_progress_bar, &my_progress_bar_value);


And here is the function called :
Code:
gboolean upgrade_progress_bar(double *value)
{
   gtk_progress_set_percentage( GTK_PROGRESS(progress_bar), *value);
   return FALSE;
}


At the end of the g_thread, calls to gdk_threads_add_idle increases used memory .. but at the end, nothing's freed.
If I comment the gdk_threads_add_idle function, used memory does not increase. So I guess I'm missing something with gdk_threads_add_idle function.

Any idea ?


Top
 Profile  
 
 Post subject: Re: The good way to manage threads for portable gtk app
PostPosted: Sun Oct 28, 2012 11:24 am 
Offline
Familiar Face

Joined: Wed Oct 17, 2012 12:23 pm
Posts: 5
Got it ... https://bugzilla.redhat.com/show_bug.cgi?id=750587

This is really annoying ... no workaround to this issue ?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group