On Wed, Jun 22, 2005 at 10:51:38AM -0400, Chris Lambacher wrote: > > > > It has nothing to do with short or long but with interactivity with > > other threads. Like a thread that can be canceled by clicking a > > button. > > > > Take the following kind of code: > > > > class Buzy(Threading): > > > > def run(self): > > while not self.is_canceled: > > calculate_step() > > gtk.gdk.threads_enter() > > show_incremental_result() > > gtk.gdk.threads_leave() > > > > def cancel(self): > > self.is_canceled = True > > > > buzy = Buzy() > > > > def On_Click(): > > buzy.cancel() > > buzy.join() > > > > > > Not look at the following scenario. buzy is calculating a step. > > The user cancels the thread, so gtk acquires the lock and calls > > On_Click which calls buzy.cancel. buzy wants to acquire the lock > > but is blocked. gtk wants to join buzy and is blocked too: Deadlock. > > > > In order to solve this I have to write On_Click as follows: > > > > def On_Click(): > > gtk.gdk.threads_leave() > > buzy.cancel() > > buzy.join() > > gtk.gdk.threads_enter() > > > > > > So here we have a litle event handler that doesn't the lock, but > > that gets in anyway and not releasing the lock will cause a deadlock. > > I see your point in this case, but writing it in this way is going to > cause you even more problems if you try to make it cross platform, ie > if you want to make it work on Windows.
IMO this point is moot here. This began with the need of gtk.gdk.threads_enter() and gtk.gdk.threads_leave() around gtk.main() in order to eliminate that the program would block when other threads did gtk or gdk calls. AFAIU this already makes the program not portable to windows. So IMO the non-portability of the programs discussed was a given. > This is neither a deficency > of Windows nor of GTK, just a by product of how Windows deals with > events in different threads and the way that X deals with events. (BTW > I know for sure this is a problem with wxWidgets as well, and I would > suspect that the same is true for Qt) > > In this case I would be updating the UI from one thread. It means > that you have to push some data over to the UI thread, but you do get > rid of all of your nasty threads_enter, threads_leave conditions. Sure but I guess you also no longer need them around the gtk.main. > In the case above I would define run something like: > def run(self): > while not self.is_canceled: > calculate_step() > data = collect_data_for_ui() > gtk.gdk.threads_enter() > gobject.idle_add(update_ui, data) > gtk.gdk.threads_leave() > > def update_ui(data): > #perform ui updating here > > return False > > Apparently you do not need the threads_enter/threads_leave pair around > the idle_add call. I always put it in because it has never broken > anything and I don't want to mess with success. > > I personally think it is a clean separation to have UI code in one > thread and processing code in another and would do things like that on > Unix even if I was never intending to port the app to Windows. I can follow you partly. First, these are supposed to be demo programs to illustrate how to do threading with gtk. If someone for some reason doesn't care about portability and wants to go the threads_enter/threads_leave way, I want to illustrate what he has to look out for. I have different versions of this demo that handle this situation differently, some portable, some not. Second your solution wont work with my application, I tried. My application has several of those buzy threads and in combination they put more idle_add calls than the main thread can handle making the whole program very sluggisch and unresponsive. I'm now writing a tube module to solve this. A Tube is like a Queue but a thread has to open a tube before it can put or get things on a tube and if all writers closed the tube a read from an empty tube will generate an exception. But most off all there is a tube_add_watch call which will monitor the tube like io_add_watch monitors a pipe or network connection.. -- Antoon Pardon _______________________________________________ pygtk mailing list [email protected] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
