[Tkinter-discuss] Proposal for thread-safe Tkinter
ggpolo at gmail.com
Tue Oct 28 21:52:58 CET 2008
On Tue, Oct 28, 2008 at 6:33 PM, C. Allen <callen at gemini.edu> wrote:
> wait a second... I have a class system, and to exercise this class system,
> and possibly as a general command line tool in the future, I access this
> class from a script meant to run in a shell. To watch progress of the system
> as it runs (it's processing data, and can take significant amounts of time)
> so I thought I'd make a nice little interface to watch the progress, and let
> the user pause and do other control commands. This is not the purpose of
> this command line tool, however, so I only bring that up based on a command
> line flag. Also, I do not call mainloop from the main thread, because it is
> doing the processing, and is the "real" program. I start another thread,
> use it (and only it) as the Tk thread.
As long as other calls to tk come from the same thread that created
the interpreter, there is no need to schedule these calls.
> This all works fine, and I never get the exception mentioned below.
The message in that error is more in the sense of "the thread that
created the tcl interpreter is not in main loop". It is also very hard
to get it with just two threads. It will try ten times, which will
last 1 second (as the current implementation), at max, to acquire the
thread that created the tcl interpreter, only then if this fails you
get that error.
> On Mon, 2008-10-27 at 15:10 -0200, Guilherme Polo wrote:
> On Mon, Oct 27, 2008 at 12:59 PM, Allen Taylor
> <Allen.Taylor at mdacorporation.com> wrote:
>> After a very helpful discussion with "Guilherme Polo <ggpolo at gmail.com>",
>> have come to the following conclusion regarding multithreaded applications
>> and Tkinter. Although Tk is technically thread-safe (if built with
>> --enable-threads), practically speaking it still has problems when used in
>> multithreaded applications.
> Now that I reread it, I see you said "Tk is technically thread-safe
> (if built with --enable-threads)". It is not true, what happens is
> that tkinter makes it thread safe by using some mutexes and scheduling
> actions to go through the thread that created the tcl interpreter,
> which otherwise would happen elsewhere. But tk isn't thread safe per
> se (only tcl, since version 8.1). At the same time, if tk is
> compiled without thread support but python has thread support, then
> tkinter fails miserably to protect against multiple threads from
> python from accessing tk.
> And again, your module does help in this case since all the
> interaction to tk will occur through main thread, independent of tk
> having thread support or not.
>> The problem stems from the fact that _tkinter
>> attempts to gain control of the main thread via a polling technique. If it
>> succeeds, all is well. If it fails, however, the application receives an
>> exception with the message "RuntimeError: main thread is not in main
>> There is no way to tell when this might happen, so calling Tk routines
>> multiple threads seems to be problematic at best.
>> The mtTkinter module I published last week
>> (http://tkinter.unpythonic.net/wiki/mtTkinter) solves this problem by
>> marshaling calls coming from multiple threads through a queue which is
>> by an 'after' event running periodically in the main loop. This is similar
>> to the technique used in many other platforms (e.g., .NET's
>> InvokeRequired/Invoke mechanism). The technique used in mtTkinter is
>> exception-safe as well, marshaling exceptions through a response queue
>> to the caller's thread.
>> If a similar technique were employed in _tkinter instead of the polling
>> technique, that would be a preferable solution. In the meantime, mtTkinter
>> will work as a good stop-gap measure.
>> Allen B. Taylor
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
-- Guilherme H. Polo Goncalves
More information about the Tkinter-discuss