On Mon, 2004-11-08 at 07:41 -0500, Dave Aitel wrote:
> Well, hopefully you don't have to learn too much. I and other people 
> have some sample code in this thread:
> http://www.daa.com.au/pipermail/pygtk/2004-February/006960.html
> 
> I didn't think about the case where the main thread is also adding lots 
> of things to the queue. One option is to have a RLock() try to acquire, 
> and if successful, to also clear the queue. That way the main thread 
> will always have a clean queue and things won't pile up.
> 
> -dave

There is another option - use Gtk's own main loop as your queue, and
anonymous pipe I/O to add the events to the queue.

Goal:  Cause the GUI event loop to execute an arbitrary callback
function when ordered to do so by one or more worker threads.

Solution:
Create a (optionally private) pipe, and associate one end (the receiver)
with a glib iosource and a custom class that abstracts away the IPC from
the callback function.
Connect your callee to the iosource, such that it is invoked when a byte
is written to the pipe from the sending end.
Associate the other end with some custom class that will act as the
sender and abstract away the IPC from the caller (note that this class
and the receiver class are the same in the Glibmm implementation).

Operation:  To make an asynchronous remote function call to the GUI
thread from the worker, the worker writes a byte to its end of the pipe.
The glib mainloop will manage receiving the byte with the poll(2) (or
WaitForMultipleObjects[Ex?] on Win32) system call, and will efficiently
wake up and notify your iosource that the byte is readable, without
wasting CPU time.  Alternatively, you can use the signal_io signal if
you want to tweak the priority that the iosource is handled relative to
other program events.  The receiver then reads the byte (and probably
ignores it - the purpose is to wake up the GUI thread, not to pass
info), and calls the registered callback function(s).

In Glibmm (C++ bindings to Glib), this is managed for the programmer by
the Glib::Dispatcher class
(http://www.gtkmm.org/gtkmm2/docs/reference/html/classGlib_1_1Dispatcher.html). 
 I have used the technique to good effect in my own code.  To my knowledge it 
doesn't exist in a neatly wrapped implementation in Glib's C library, but you 
should be able to make one that works for PyGTK based on my description.  I'm 
still mostly just familiar with Gtkmm, but since all of the primitives are in 
the underlying C library, it should be doable from Python.

HTH,
-Jonathan

> Thomas Mills Hinkle wrote:
> 
> >Okay, so I think between this and the other thread, I'm gathering that
> >gtk.threads_enter() and gtk.threads_leave() will not keep me safe, and
> >that the recent bug I found is the first of many I may have to encounter
> >over the life of my app,esp. if I port it to Windows.
> >
> >So I'm going to add learning-about-queue's to my to-do list and hope
> >that that makes my threading woes go away. I probably won't get to this
> >until the weekend. The bit of sample code Tim Evans posted in response
> >to Jamie Norrish's problem will help me get started. Are there other
> >queue examples that I've just missed i.e. in the FAQ?  If not, perhaps
> >it would be worth piecing one together and referencing it in the section
> >of the FAQ that describes gtk.threads_enter() and other alternatives
> >(generators, weightless threads).
> >
> >Tom
> >_______________________________________________
> >pygtk mailing list   [EMAIL PROTECTED]
> >http://www.daa.com.au/mailman/listinfo/pygtk
> >Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
> >  
> >
> 
> _______________________________________________
> pygtk mailing list   [EMAIL PROTECTED]
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
-- 
Jonathan Brandmeyer <[EMAIL PROTECTED]>

_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to