Re: Problems with Threading Concept
- From: James Scott Jr <skoona verizon net>
- To: naveen <naveen galieosoft com>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: Problems with Threading Concept
- Date: Mon, 19 Feb 2007 21:04:44 -0500
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]