Re: Proper way to provide gtk+ app with asynchronous data?



Excuse me for jumping in the fray, but let me expand on this because it's
simple to use threads if you use some simple rules:

In your primary thread (i.e. the thread that will eventually call
gtk_main():
o you MUST call g_thread_init(NULL); - call this before calling
gnome_init();
o when you call gtk_main() put a gdk_threads_enter() and gdk_threads_leave()
around it, i.e.
  - gdk_threads_enter()
  - gdk_main()
  - gdk_threads_leave()
  I do not know why this must be done, just that it must be done.  I am not
sure it even must be done, just that everybody does it!

In the thread that does the asynchronous update on the display (the
secondary thread)
o once you get your data that will change the screen,
  - call gdk_threads_enter()
  - then update the screen doing whatever gtk calls you do normally
  - you can OPTIONALLY (and probably want to) call gdk_flush() - if you
don't, the screen won't update promptly.
  - then call gdk_threads_leave()

If you ever call gdk_threads_enter() twice withouth calling
gdk_threads_leave() first, your screen will lockup.  That's very fun.  You
need to go to another machine or log in on the console (ALT-CTL-F1) and
kill -9 your program.  This *will* happen to you.

If you don't call gdk_threads_enter() before updating the screen, you'll get
a mysterous error talking about asynchronous something stuff, and your
program will crash.  I don't remember the exact error, but you'll probably
do it at least once.  When you get this error, it's because you didn't call
gdk_threads_enter() from your SECONDARY thread first.  This problem will be
INTERMITTENT and RANDOM, so you won't be sure you have this error until you
run the code - a lot.

Never call gdk_threads_enter() from your primary thread except around
gdk_main()

I have a suggestion or 2 about all this BTW:

1) gdk_threads_enter() should have a reference count to detect when it's
called twice and notify you when it is called twice.  It might be nice to
ALLOW gdk_threads_enter() to be called multiple times by the same thread as
long as a number of matching gdk_threads_leave() gets called.

2) Also, it seems silly to me that you need to surround gdk_main() with
gdk_threads_enter() and gdk_threads_leave() - calling g_thread_init(NULL)
should do that for you by setting some internal variable that will cause
gdk_main() to do it automatically.  It's pretty esoteric and odd the way
it's currently setup.

I'm also curious why gtk_threads_init() doesn't just do the
gdk_threads_enter() and gdk_threads_leave() for ALL GTK functions?  GTK
knows the PID of the process that called gnome_init() - if the PID is
different than the primary threads, why not just handle gdk_threads_enter()
and .._leave() for you by all the gtk functions?  I know this is a major
overhaul, but it doesn't seem like it would incurr much of a penalty in
performance, especially considering how much error checking is done already
on casting variables.

-Rich


----- Original Message -----
From: "zze-DEPREZ Olivier FTRD/DMI/SOP"
<olivier deprez rd francetelecom com>
To: "Dmitry M. Shatrov" <zzidre mail ru>; <gtk-list gnome org>
Sent: Thursday, July 08, 2004 11:35 PM
Subject: RE : Proper way to provide gtk+ app with asynchronous data?


> Well, if you meant you have one thread who sends the data (non necessarily
graphical, eg: the one on your other machine), and one thread who displays
it, you just can create another thread who reads it
>
>
>
>       pthread_create(&thread_id, NULL, (void *(*)())readStatPaquets,
NULL);
>
>   gdk_threads_enter();
>   gtk_main();
>   gdk_threads_leave();
>
>
>
> void
> readStatPaquets()
> {
>
>       gdk_threads_enter();
> -----Message d'origine-----
> De : gtk-list-bounces gnome org [mailto:gtk-list-bounces gnome org] De la
part de Dmitry M. Shatrov
> Envoyé : jeudi 8 juillet 2004 09:32
> À : gtk-list gnome org
> Objet : Proper way to provide gtk+ app with asynchronous data?
>
>
> Hello.
>
> I'm going to display graphically data that arrives from another machine.
It must be displayed as soon as possible, so periodic polling does not suite
my needs. How to implement this properly?
>
> In my case there is one thread which receives data and an UI thread with
an event loop, I think about making a new event source (g_source_new, I
mean), is it correct or maybe there's a simpler solution?
>
> Thank you.
> Dmitry
>
> _______________________________________________
> gtk-list mailing list
> gtk-list gnome org http://mail.gnome.org/mailman/listinfo/gtk-list
> _______________________________________________
> gtk-list mailing list
> gtk-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-list
>




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