[ this repeats the note with better formatting; hopefully]

Tobias,

This response may be a little off topic.  But as I have followed this thread I 
understand your are moving some application to linux from MS.  Moreso, you are 
planning on using gtk to get that port done.  Here is a little of my experience 
with gtk threaded program design.

1. Having gtk thread security features turned on is required if you plan to 
call gtk_ api's from more than one thread: Which you should NOT try to do.
    * If your app will be multi-threaded be sure to enable these protection 
feature as described. 
http://developer.gnome.org/doc/API/2.0/gdk/gdk-Threads.html 
    * And use the glib set of api's for creating and managing threads, as 
described here: http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html

2. Spend some time devising a way to collect data values that need to be 
visually represented in gtk inside a container or memory structure that you can 
g_new0() allocate.  
    * Then pass that pointer from the background thread to the foreground GTK 
main thread for display or updating
        ** maybe using GAsyncQueue to pass the pointers
        ** GAsyncQueue will also cause a thread to block; good for background 
threads waiting on work, BAD for the GTK main thread and its contructs.
        ** apis which act on the GAsyncQueue behave somewhat like the MS 
postMessage() api
                *** the sendMessage is synchronous and has no GTK/GLIB 
equivilent.  One way to overcome this is to
 actually share a set of user.functions() and a common memory structure using 
glib's g_mutex apis.  Be sure to call these shared(between threads) 
user.functions from a g_idle/g_timeout based functions in the gtk main thread 
when targeting the gui.
                *** If you don't call any gtk/gdk api's from another thread 
then you will not need to call gdk_threads_enter/exit()
        ** For gtk main thread to background thread interchanges look over the 
g_idle/g_timeout set of apis and potentially g_io_channel/watch apis; along 
with  g_mutex 'es where needed.
                *** gapcmon.sourceforge.net, gfhcm.sourceforge.net contain 
working examples of tcp socket intensive gtk/C programs using these methods.

        ** If you look at how gtk suggest you setup for multi-threaded program, 
it describes wrapping the call to gtk_main() with ( gdk_threads_enter(); 
gtk_init(); gtk_window...;gtk_main();gtk_threads_exit() ).  What is not so 
obvious is that this protects most button and g_signal callbacks.   g_idle... 
g_timeout... g_thread... based functions are not protected by the gtk_main loop 
because they occur outside its control - so they must have 
gdk_threads_enter/exit wrappings just arround the gtk_... call only.
                *** You need to consider using gdk_threads_enter/exit in any 
g_idle/g_timeout/g_thread/g_io_ based routine
                *** if you follow me thus far, then you will never call a 
gtk/gdk routine from outside the gtk_main loop or thread; except for maybe 
g_io_watch based functions.

3. Socket based, and other OTHER PROCESS, communication wheter a pipe or a 
socket or orther mechanism may lend itself to g_io_channel and g_io_watch based 
apis.
        ** Look at a few example of how the glib feature set works;  it ends up 
executing during the gtk_main loop thread/time be can be very useful in 
handling external process based communication.
        ** If you find that this (g_io_watch() ) method works for you, consider 
creating your own glib loop (g_main_loop_run()) in a background thread to get 
your io processing off the gtk_main timeslice
4. Finally, be
 careful how you implement or use classic unix signals:  Danger, Danger Will 
Robinson..

I can not stress enough that you need to buy the book, readit, and workout some 
off-project tests before pounding out a ported application.  You will find 
gtk/glib to have a rich set of widgets and programming constructs that make 
using it almost fun.

I hope some of what I've said help your quest.

James,
(a.k.a Skoona)

----- Original Message ----
From: "[EMAIL PROTECTED]" <[EMAIL PROTECTED]>
To: Tobias Rapp <[EMAIL PROTECTED]>
Cc: gtk-app-devel-list@gnome.org
Sent: Thursday, March 29, 2007 4:15:54 AM
Subject: Re: Thread-save posting of events

On 3/29/07, Tobias Rapp <[EMAIL PROTECTED]> wrote:
> Rick Jones wrote:
> > I've only come across it while looking for other things, but perhaps the
>
 >  GAsyncQueues stuff would be useful for thread-to-thread comms?
> >
> > http://developer.gnome.org/doc/API/2.0/glib/glib-Asynchronous-Queues.html
>
> That looks exactly like the thing I'm searching for. I had a look at the
> API documentation before but don't know how I missed that one. Thanks!
>
> > You probably still need watch routines executing the the various event
> > loops (guessing).
>
> Yes, maybe I have to add an idle handler for the event loop with
> g_idle_add() (as proposed by John) and do a g_async_queue_try_pop() in
> there...

Actually no, you can just use g_idle_add() like this:

  my_thread()
  {
    for(;;){
      // worker thread main
 loop
      Thing *stuff;

      stuff = g_new( Thing, 1 );
      calculate_thiing( stuff );
      g_idle_add( handle_stuff, stuff );
    }
  }

Then the function handle_stuff will be run by your program's main loop
thread when it's next idle:

  handle_stuff( Thing *stuff )
  {
    update_gui( stuff );
    g_free( stuff );
  }

You might need something to stop the worker filling RAM with
unprocessed packets of stuff if the GUI thread can't keep up with the
worker's rate of production.

GAsyncQueue can be used to communicate between two threads without
involving the main loop at all. If one of your threads is running the
GTK main loop, then g_idle_add() is far
 simpler.

John
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list








_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to