threading choices



Hi all,

it seems that are two (or more) choices how to work with threads in
gtk. You can #1 use a global lock and call gtk from any thread, or you
can #2 limit your gtk calls to the main loop and not use the global
lock. As far as I understood, method #2 is portable to win32, and
method #1 is not? Is that correct? What are other reasons to choose
for one of these approaches? Are there any other important approaches
that need attention?

regards,
   Olivier
--------------------------method #1 -----------------------------------------
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>

/* this example can call gtk functions from different threads and uses
the global lock.
 * this is *not* portable to win32 !!!!!!
 */

static gboolean thread_finished(gpointer data) {
        GtkWidget *w=data;
        
        /* because this is called by gdk_threads_idle_add_full the code
         * in this function is executed within the global lock. Call gtk
         * whenever you want, no need to call gdk_threads_enter() / gdk_threads_leave()
         */
        
        
        return FALSE; /* we're done, return FALSE */
}


static gpointer handle_thread(gpointer data) {
        
        /* do things that take a lot of time
        you can do anything GTK here provided that you
        get the global lock first */
        
        gdk_threads_enter();
        /* do anything gtk here */
        gdk_threads_leave();
        
        /* an example to call an idle function that will automatically get
the global lock for you */
        gdk_threads_idle_add_full(G_PRIORITY_LOW,thread_finished_lcb, data,NULL);
}

int main(int argc, char **argv) {
        GtkWidget *w
        GError *gerror=NULL;
        g_thread_init();
        gdk_threads_init(); /* call gdk_threads_init() if you want to call
gtk from multiple threads */
        
        g_thread_create_full(handle_thread,w,0,FALSE,FALSE,G_THREAD_PRIORITY_LOW,&gerror);

        gdk_threads_enter(); /* do gtk things inside the gtk lock */
        gtk_init(&argc, &argv);
        w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_widget_show_all(w);
        gtk_main();
        gdk_threads_leave();
        return 0;
}

--------------------------method #2 -----------------------------------------
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>

/* this example calls gtk functions only in the main loop, and
never calls gtk functions from a thread. */


static gboolean thread_finished(gpointer data) {
        GtkWidget *w=data;
        
        /* this is executed in the main loop, not in the thread */
        
        return FALSE; /* we're done, return FALSE */
}


static gpointer handle_thread(gpointer data) {
        
        /* do things that take a lot of time
        but don't do anything GTK here */
        
        g_idle_add_full(G_PRIORITY_LOW,thread_finished_lcb, data,NULL);
}

int main(int argc, char **argv) {
        GtkWidget *w
        GError *gerror=NULL;
        g_thread_init();
        gtk_init(&argc, &argv);
        w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_widget_show_all(w);
        g_thread_create_full(handle_thread,w,0,FALSE,FALSE,G_THREAD_PRIORITY_LOW,&gerror);
        gtk_main();
        return 0;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]