On Mon, 2007-02-19 at 12:42 +0530, naveen wrote: > #include <gtk/gtk.h> > #include "stdio.h" > #include <pthread.h> > > int flag=1,toggle=0; > int i=0; > pthread_t yes_tid; > > void hello() > { > > while (flag) > { > gdk_threads_enter (); > > printf ("%d %d\n",i++,flag); > if (gtk_events_pending()) > gtk_main_iteration(); // Handle unprocessed GTK events > > gdk_threads_leave (); > } > > } > > void hello_print( GtkWidget *widget, > gpointer data ) > { > if(toggle==0) > { > toggle=1; > flag=1; > pthread_create (&yes_tid, NULL,(void *)hello, NULL); > } > else > { > flag=0; > toggle=0; > } > > } > int main(int argc, > char *argv[] ) > { > > GtkWidget *window; > GtkWidget *button; > g_thread_init (NULL); > gdk_threads_init (); > > gdk_threads_enter (); > > gtk_init (&argc, &argv); > > /* create a new window */ > window = gtk_window_new (GTK_WINDOW_TOPLEVEL); > > g_signal_connect (G_OBJECT (window), "destroy", > G_CALLBACK (gtk_main_quit), NULL); > > gtk_container_set_border_width (GTK_CONTAINER (window), 100); > > button = gtk_button_new_with_label("click it"); > > g_signal_connect (G_OBJECT (button), "clicked", > G_CALLBACK (hello_print), NULL); > > gtk_container_add (GTK_CONTAINER (window), button); > > gtk_widget_show (button); > gtk_widget_show (window); > > gtk_main (); > > gdk_threads_leave (); > > return 0; > } >
Naveen, Look at these changes. A B C A. gdk_thread_enter/leave() is used to surround the gtk_main loop and any gtk_* functions called from another thread. In A you are not calling and gtk_ functions. I see that you plan too though, when you do surrond just the group of calls with the gdk_thread... statements. Also, you should strong consider using g_thread_create() and the glib set of functions for multithreaded gtk applications. see "devHelp", a locally installed api documentation tool, for how-to usage of the glib functions B. You have re-implemented the gtk_main() loop here; which is a vaild construct -just not needed at this level programing. The gtk_main loop in the first (main) thread is active and running, trying to handle ALL gtk commands, this is simply a duplication that adds nothing. C. In the correct place, immediately before and after, the gtk_main() these calls serve a vaild function to serialize access to gdk/gtk global variables. Managing the resource action will become more difficult when you start adding more threads or gdk/gtk functions in other threads. Focus on starting out right and following this before/after guideline got gtk_main. General Comment: The design of a multi-threaded GTK application deserves some time investment and design consideration. Read this tutorial link: "http://www.gtk.org/faq/#AEN482". Also, read this for GLIB thread functions, the preferred choice for GTK multi-threaded programming: "http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html". You are going to find very quickly that using gdk/gtk functions in anything except the main thread is a real pain to control and manage; BUT it can and has been done by many. As a design point you should minimize the need to do so. Given that: consider this for IO related thread-like work, GLIB provide the g_io_add_watch()/g_io_channel... set of functions that are pre-integrated into GTK/GDK cleanly. For other programming actions GDK/GTK/GLIB provides a collection of thread-like constructs to run functions via timers and idles - g_timeout_add()/g_idle_add(). Most of what I have mentioned thus far does not require the use of gdk_thread_enter/leave(), and are considered multi-threaded in behaviour. Lastly, g_thread_create() and the whole GLIB collection of thread support routines are available. As are a collection of inter-thread communication methods like GASyncQueue(), mutex's, semaphores, and conditions. Combined these standard tools and functions will allow you to create high performance applications that use GDK/GTK graphics capabilities without hindrance. Just do a little design work first, and keep asking questions and looking at existing code that uses these api's. James, #include <gtk/gtk.h> #include "stdio.h" #include <pthread.h> int flag=1,toggle=0; int i=0; pthread_t yes_tid; void hello() { while (flag) { /*-A gdk_threads_enter (); -- your not going gtk thing here so you don't need this !! */ printf ("%d %d\n",i++,flag); /*-B if (gtk_events_pending()) -- never do this unless your certain what your doing */ /* gtk_main_iteration(); */ /*-A gdk_threads_leave (); --- again not needed */ } } void hello_print( GtkWidget *widget, gpointer data ) { if(toggle==0) { toggle=1; flag=1; pthread_create (&yes_tid, NULL,(void *)hello, NULL); } else { flag=0; toggle=0; } } int main(int argc, char *argv[] ) { GtkWidget *window; GtkWidget *button; g_thread_init (NULL); gdk_threads_init (); /*-C gdk_threads_enter (); -- too early */ gtk_init (&argc, &argv); /* create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_container_set_border_width (GTK_CONTAINER (window), 100); button = gtk_button_new_with_label("click it"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello_print), NULL); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show (button); gtk_widget_show (window); gdk_threads_enter (); /*-C -- correct place for this */ gtk_main (); gdk_threads_leave (); return 0; } James Scott, Jr. Registered Linux User #270764 FC6 on Dual AMD-MP 2400+ Author: {gfhcm, gkrellfah2,gapcmon,giw}.sourceforge.net http://mysite.verizon.net/skoona/index.html
_______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list