Ivan Pozdeev <ivan_pozd...@mail.ru> added the comment:

> This seems very complicated. The official line on threads for Tk has always 
> been to make all Tk calls from one thread, which is at least predictable and 
> comprehensible. Is there any reason for Tkinter to suggest anything different?

Tcl/Tk doesn't have a notion of a blocking event loop like other GUI toolkits 
do. Any code using Tcl must essentially call Tcl_DoOneEvent/`update` regularly 
at strategic points.
This allows to work completely in one thread -- i.e. even if the OS has no 
threads whatsoever. Tcl/Tk is very old, and this model made perfect sense back 
then (and still does in some scenarios -- e.g. 
https://stackoverflow.com/questions/4083796/how-do-i-run-unittest-on-a-tkinter-app
 -- so there's no point in dropping it).
If we'll be updating tutorials (the reference is a priority though), we 
definitly need to demonstrate this option.

The current best practice for GUI programming is different. There's one "GUI" 
thread that runs just the event loop constantly, and other threads submit 
GUI-related work items into its queue (whatever they are called - "messages", 
"events", "futures"...). Likewise, for any lengthy task, the GUI thread spawns 
worker threads that report back on their progress via the same queue.

All more or less modern GUI toolkits implement and advertize this model as the 
primary one -- as does Tkinter. So, at least the work item submitting API must 
be thread-safe (and in other GUI tooltikts, it is -- see 
https://mail.python.org/pipermail/python-dev/2018-May/153359.html ).
For programmer's convenience, Tkinter does this transparently: whenever and 
whatever Python thread a call is made from, it makes it look for the Tcl 
interpreter as if all calls are sequential, and it enforces correct order for 
interdependent calls.

A great deal of complexity comes from the fact that Tcl's threading model is 
very unothodox. Tcl's team seem to only have accepted threads reluctantly and 
to have been campaigning against threads for years before that 
(https://wiki.tcl.tk/38128 is arguably the most egregious case).
So, what they did is tie a Tcl interpreter to an OS thread (by using thread 
local storage for its data). Long story short, no-one else does it like this 
(at least, I've never seen or heard of anything of the kind), and this is not 
what thread-local storage is meant for 
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4324.html lists some 
use cases for TLS). The best practice is to use locks to ensure orderly access 
to the shared state instead. My guess for the decision is it was the easiest 
way to migrate the code base (yet still tough as https://wiki.tcl.tk/1370 seems 
to hint), and it kinda lines up with that "single thread" mindset.

Tkinter thus has to jump through hoops for calls coming from other threads 
(since for Python, it absolutely doesn't matter which OS thread makes a call).
All the limitations when using threaded Tcl (see the letter attached to the 
ticket for details) come solely from this tying. With nonthreaded Tcl (bugs 
nonwithstanding), it's free-for-all, everything can be called from everywhere. 
The only upside is that with threaded Tcl, calls to different interpreters can 
run in parallel.

> This ignores the compilation issue of course. FYI, the Tcl core group will 
> probably eliminate the possibility of doing non-threaded builds in the 
> future, though with backwards compatibility issues, that's neither here nor 
> there.

I know. Me asking them for clarifications from Tcl/Tk's side seems to have 
triggered it, in fact. Since the sole offender is their threading model, the 
way is to show them how it's defective and work towards improving it. We have 
at least a few years with old versions, and the limitations seem tolerable at 
first glance anyway, so that's not a priority.

> do you know how to identify the tcl/tk build on MacOS or Linux?

The same way Tkinter does @_tkinter.c:624 . The equivalent Python is 
`tkinter.Tk().tk.call("array","get","tcl_platform","threaded")`

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue33479>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to