WARNING: The threading support is still somewhat experimental, and it has only seen reasonable testing under Linux. Threaded code is particularly tricky to debug, and it tends to show extremely platform-dependent behavior. Since I only have access to Linux machines, I will have to rely on user's experiences and assistance for this area of IPython to improve under other platforms.
IPython, via the -gthread , -qthread, -q4thread and -wthread options (described in Sec. 5.1), can run in multithreaded mode to support pyGTK, Qt3, Qt4 and WXPython applications respectively. These GUI toolkits need to control the python main loop of execution, so under a normal Python interpreter, starting a pyGTK, Qt3, Qt4 or WXPython application will immediately freeze the shell.
IPython, with one of these options (you can only use one at a time), separates the graphical loop and IPython's code execution run into different threads. This allows you to test interactively (with %run, for example) your GUI code without blocking.
A nice mini-tutorial on using IPython along with the Qt Designer application is available at the SciPy wiki: http://www.scipy.org/Cookbook/Matplotlib/Qt_with_IPython_and_Designer.
As indicated in Sec. 5.1, a special -tk option is provided to try and allow Tk graphical applications to coexist interactively with WX, Qt or GTK ones. Whether this works at all, however, is very platform and configuration dependent. Please experiment with simple test cases before committing to using this combination of Tk and GTK/Qt/WX threading in a production environment.
Be mindful that the Python interpreter switches between threads every
bytecodes, where the default value as of Python 2.3 is
This value can be read by using the sys.getcheckinterval()
function, and it can be reset via sys.setcheckinterval(N).
This switching of threads can cause subtly confusing effects if one
of your threads is doing file I/O. In text mode, most systems only
flush file buffers when they encounter a `\n'.
An instruction as simple as
print >> filehandle, ``hello world''
actually consists of several bytecodes, so it is possible that the
newline does not reach your file before the next thread switch. Similarly,
if you are writing to a file in binary mode, the file won't be flushed
until the buffer fills, and your other thread may see apparently truncated
files.
For this reason, if you are using IPython's thread support and have
(for example) a GUI application which will read data generated by
files written to from the IPython thread, the safest approach is to
open all of your files in unbuffered mode (the third argument to the
file/open function is the buffering value):
filehandle = open(filename,mode,0)
This is obviously a brute force way of avoiding race conditions with the file buffering. If you want to do it cleanly, and you have a resource which is being shared by the interactive IPython loop and your GUI thread, you should really handle it with thread locking and syncrhonization properties. The Python documentation discusses these.
Fernando Perez 2007-11-29