-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elaborate/reference the "multiple threads are not an issue in Python 3.x" #5
Comments
It has been a long time since I researched multi-threading with Tkinter, so please bear with me as I try to recall things as well as I can from a site that apparently is no longer available. My only reference would be the statement in the wiki of this repository:
I made this statement based on a forum post by the original author of the module, but unfortunately after spending the better part of an hour searching for the post, I concede that I can no longer find it. My leaky-as-a-cauldron memory will have to serve as a reference instead, I'm afraid. The forum post was posted in a thread that discussed mtTkinter in some form or another, and the original author stated that mtTkinter was not useful for Python 3, as in Python 3 Tcl is compiled with the thread-safe flag (which is, I believe, also the case for the latest Python 2 versions). I understand if you find this a very weak explanation of why I stated what I did, and reading through my explanation, I cannot disagree with you if you do. Going back down the rabbit-hole, I have looked up the archived version of the page I originally got the module from (as the original page is no longer available). My understanding, based on this and the reading that I did over a year ago, was as follows: Tk is not thread-safe, unless it is built with the thread-safe flag. However, the Tcl-interpreter must also be built with the thread-safe flag to ensure thread-safety for Tkinter. This understanding was supported by the fact that after I ported the program for which I initially used mtTkinter to Python 3 without mtTkinter, I no longer had any issues. However, given the supporting references you have provided, perhaps this understanding is wrong and it only worked in my case because of some weird coincidence. The reproduction of threading issues in Tkinter is spotty, and it could be that even though I have used Threads multiple times now in Python 3 with Tkinter, I have just never encountered issue, and that doesn't have to mean that because I can't reproduce any issues with threading in Python 3 doesn't mean there aren't any (call it tunnel vision, if you will). Conclusion If you have any other questions or remarks, please don't hesitate to post them. I will get to them as soon as I can. |
I have removed all references to Python 3 thread-safety from the Wiki and the README, so I'm going to close this issue now. Thank you for pointing this out to me, I wouldn't have discovered on my own. |
If the sources are not available, let's cut the middleman and check the claims directly.
https://github.com/python/cpython-source-deps/blob/tcl-8.5.19.0/win/makefile.vc#L73 (location deduced from
https://github.com/python/cpython-source-deps/blob/tcl-core-8.6.6.0/win/makefile.vc#L74 (py3.6 head):
https://github.com/python/cpython/blob/master/PCbuild/tcl.vcxproj#L54 : So, 2.x does not build Tcl with thread support while 3.x does. What does that mean for "thread safety"?
So, it does look like threaded Tcl is thread safe in that it protects shared state with mutexes and allows unrestricted calls to interpreters associated with other threads. It's not clear how much TKinter uses this though.
Now, let's see the differences in Tkinter... |
Sorry for the late reply. You can understand that this research took some time. I even cut it short -- before having analyzed Tkinter -- to be able to reply in a timely manner at all. |
@native-api Thank you for your in-depth research into the specifics of the Tcl building process and how the thread-safety works! Research like that indeed takes time, and if you get around to also researching the Tkinter specifics, I would very much like to hear them. That Tcl is designed to be thread-safe indeed does not guarantee that Tkinter is thread-safe inherently, and even if it is designed in such a manner, it might contain some implementation issues that people have encountered over time and thus resulted in weird issues that were solved when using a guarenteed thread-safe implementation. |
In As per _tkinter.diff.zip, the changes between 2 and 3 are:
This means that if there's a reason for discrepancy, it should lie in the relevant logic itself, probably resulting from the threaded vs non-threaded Tcl. |
Okay, got the results on the logic, too. All in all, for non-threaded Tcl, all Tcl calls are wrapped with locks (see comment at https://github.com/python/cpython/blob/master/Modules/_tkinter.c#L162 ) . So, they should be thread-safe and any race conditions are due to bugs. And I did find such bugs: in The destruction in So, In Py3, the example |
Wow. Just wow. That is some very impressive an thorough research. I have actually encountered the bug you describe before, without even realizing it was related to this. Thus, if I understand correctly, after your patch is merged Thank you for clearing this up! I really appreciate the deep dive and I think it is really great that you got to the bottom of this. |
Yes, exactly. I've looked through all the other uses of the Tcl lock and run the example from the ticket in a loop for a few hours without a single error. So, no other affecting bugs in sight.
I'm okay with that. Since you don't need (and shouldn't) to go into too much detail, there's nothing I can do here that you can't. Moreover, since you saw the events from an outside perspective, it'll be easier for you to describe it in layman's terms. |
@wekay102200 So, a few things before I actually get to your question:
Then, on to your question: There are three solutions:
Now, I still want to leave this issue open so the information is easier to find. However, as your issue is not related to this thread, you should open another issue, if your issue is related to |
Wherever I look, everyone says that Tk/Tkinter has no facilities to call/send events into the main thread (even in Py3). So the only option is to poll some
queue
or something from it by repeatedly calling.after
. And thatmttkinter
is the only real salvation.So, stating that in Python 3.x, doing
tkinter
calls from another thread in not a problem as you do is quite a groundbreaking claim to make!Do you have any references to back it with?
The text was updated successfully, but these errors were encountered: