This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Honest Abe
Recipients Honest Abe, PythonInTheGrass, amaury.forgeotdarc, asvetlov, belopolsky, cgohlke, loewis, pitrou, terry.reedy
Date 2013-03-18.21:06:14
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1363640774.64.0.222707045694.issue11077@psf.upfronthosting.co.za>
In-reply-to
Content
I have been researching this due to the recurring recommendations, on stackoverflow.com, to use the queue.Queue + after() technique when using multiple threads.

———

From comments in _tkinter.c:

The Tcl interpreter is only valid in the thread that created it, 
and all Tk activity must happen in this thread, also. 
That means that the mainloop must be invoked in the thread that
created the interpreter. Invoking commands from other threads is possible; _tkinter will queue an event for the interpreter thread, which will then execute the command and pass back the result. If the main thread is not in the mainloop, and invoking commands causes an exception; if the main loop is running but not processing events, the command invocation will block.

http://hg.python.org/cpython/file/ef8ea052bcc4/Modules/_tkinter.c#l174

/* This is the main entry point for calling a Tcl command.
It supports three cases, with regard to threading:
1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in
the context of the calling thread.
2. Tcl is threaded, caller of the command is in the interpreter thread:
Execute the command in the calling thread. Since the Tcl lock will
not be used, we can merge that with case 1.
3. Tcl is threaded, caller is in a different thread: Must queue an event to
the interpreter thread. Allocation of Tcl objects needs to occur in the
interpreter thread, so we ship the PyObject* args to the target thread,
and perform processing there. */

http://hg.python.org/cpython/file/ef8ea052bcc4/Modules/_tkinter.c#l1314

———

The following quote seems to imply that it is thread safe:

"Invoking commands from other threads is possible;
_tkinter will queue an event for the interpreter thread, 
which will then execute the command and pass back the result."

But... Allen B. Taylor, author of mtTkinter, states:

The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads. If it succeeds, all is well. If it fails (i.e., after a timeout), the application receives an exception with the message: "RuntimeError: main thread is not in main loop".

http://tkinter.unpythonic.net/wiki/mtTkinter

This seems to be somewhat validated by the first quote from the source code.
However, the statement "main thread is not in main loop"
seems backwards to me. Wouldn't a loop be in a thread?
How can the thread that spawned the mainloop ever be inside of the mainloop? Note that all of my experience is with Python, not C.
History
Date User Action Args
2013-03-18 21:06:14Honest Abesetrecipients: + Honest Abe, loewis, terry.reedy, amaury.forgeotdarc, belopolsky, pitrou, asvetlov, cgohlke, PythonInTheGrass
2013-03-18 21:06:14Honest Abesetmessageid: <1363640774.64.0.222707045694.issue11077@psf.upfronthosting.co.za>
2013-03-18 21:06:14Honest Abelinkissue11077 messages
2013-03-18 21:06:14Honest Abecreate