Re: Thread-save posting of events



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.

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 
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.htmlSpend 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 
updatingmaybe using GAsyncQueue to pass the pointersGAsyncQueue 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() apithe 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 function in the gtk main thread.
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 callback 
except for g_timeout... g_thread... based functions;  as those callbacks occur inside the current gtk_main 
loop.You need to consider using gdk_threads_enter/exit in any g_timeout/g_thread/g_io_ based routineif 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.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 timesliceFinally, 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: "jcupitt gmail com" <jcupitt gmail com>
To: Tobias Rapp <t rapp noa-audio com>
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 <t rapp noa-audio com> 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







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