On Mar 28, 2007, at 6:03 PM, Antonino Ingargiola wrote: > On 3/28/07, Ken McIvor <[EMAIL PROTECTED]> wrote: >> You should probably do the acquisition asynchronously by running it >> in a separate thread. <snip> > > That's exactly what I'd like to do. The problem is that if I run > gtk.main() (the gtk main GUI loop) in a separate thread the program > stops until I do something on the GUI (for example passing the mouse > on it).
Does it do this if you run gtk.main() in the main thread (e.g. the interpreter prompt) while doing something else in a background thread? > My understanding so far is the following. When the function > that execute gtk.main() is executed, python doesn't switch thread > until either 100 bytecode instructions are executed or since an I/O > (potentially) blocking operation in executed. I think you're more or less correct but are unaware of one important factor. Here's my understanding of how multithreading works in Python... Thread switching is controlled by something called the Global Interpreter Lock, which is implemented in an abstract way on top of an OS lock/mutex object. Only one Python thread runs at a time because the Python interpreter requires a thread to hold the GIL before it can execute bytecode instructions. The running thread holds the GIL while is executes 100 instructions. During this time other Python threads block waiting to acquire the GIL. After it has executed its 100 instructions, the running thread releases the GIL and then attempts to reacquire it. The OS ensures that things are fair by preventing one thread from reacquiring the GIL over and over again when other threads are also waiting for it. Python doesn't actually detect you do something that will block the thread, like an I/O operation. Instead, the C code implementing an I/ O operation like file.write() releases the GIL before performing the operation. This allows a different thread to acquire it and run some more bytecode instructions while the first thread performs its I/O operation. > When I'm doing nothing on the GUI application, neither 100 byte > code instructions are executed in the thread neither an I/O call is > performed, so the whole program (including the *other* threads) > stalls. I'm not sure on the details, but the C code that implements gtk.main () almost certainly releases the GIL before running the GUI event loop. Otherwise things like iPython wouldn't be able to run the GUI in a separate thread. So, that's probably not the problem. It's possible that there's another lock that's used to protect access to the gtk module. If that's the case you could be causing deadlock by calling making gtk calls from multiple threads. In my experience it's best to stick to the one-thread rule: the thread that runs the GUI's event loop is the only thread that's allowed to do anything related to the GUI. > Basically, I don't know which is the right way to put a Gtk GUI in > background, while another thread get the data asynchronously. You probably want to put the GUI in the main thread. The main thread is the only thread in a Python program that receives the KeyboardInterrupt exception when the process receives a SIGINT (i.e. when the user hits ^C in the shell). Also, most Python GUI toolkits require their event loops run from the thread that originally imported the module. > BTW, the timer idea is good and eliminates the need to call > asynchronously the GUI thread to update the plot, which seems (the > latter case) not very simple to do. Yep. It's impossible to inject arbitrary code into a Python thread; the thread has to figure out what it's supposed to do by periodically polling something or retrieving some kind of message by blocking on a queue. Blocking on a queue isn't an option for the GUI thread. You might be able to trigger Gtk signals from a separate thread but in my experience tricks like that can be, well, tricky. > Thanks to your suggestion to use the image.set_data method I've > created a simplified script (pasted at the end) that demonstrate how > to do live-update while acquiring (jep!). Glad I could help! :-) > The last think I'm not yet able to do is to update the colorbar to > autoscale with the new incoming data. The the script that follows > tries to update the colorbar too but it does not work (on matplotlib > 0.87 at least). I have no idea if this will help, but you might need to call AxesImage.changed() after calling AxesImage.set_data(). Ken ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users