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
multiprocessing won't work with Tkinter (under Linux) #49777
Comments
Hello, The attached test case, which uses multiprocessing module to run Tkinter The test case is a trimmed version of much larger program but it still I may have overlooked something but as far as I review my code, I |
The script tk_test.py produces the window with one button after one So importing Tkinter after the fork seems to solve the problem. |
Hello Jani Hakala, Thank you very much for working on the case I created. I have confirmed observation that the problem is fixed under Linux if However, this remains a problem for me and most other Tkinter programmers. This is because otherwise all Tk constants need to be prefixed with If I import Tkinter module after fork(), I cannot use from Tkinter *. Is there any way to figure out the cause of this problem? Thank you for your help. Aki- |
You can do something like Or you could just do 'from Tkconstants import *' in your tk_test.py |
Hello Jani Hakala, Thank you for your suggestions. The first suggestion worked ... almost. It would be nice if the problem is solved so that I don't need to resort I will play around trying to find a bit nicer workaround. Thank you! |
We ran into this. Forking before importing Tkinter worked for us. We did the following which seems pretty clean: main.py application.py |
I recently got hit by this bug on 64-bit ubuntu 13.04, with python 3.3.1 and tcl/tk 8.5.13 installed from the Ubuntu repositories. However, I tried building the same versions of tcl, tk, and python locally, and couldn't reproduce the bug. I also built python 3.3.2 with several releases of tcl/tk. With 8.5.8 and earlier, I get a buffer overflow. With 8.5.9-14 and recent trunk versions of tk and tcl, everything works. With 8.6.0, I get the hang. In the tcl/tk versions where the script works correctly, if I also have some tkinter code (such as instantiating a Tk and a Button) in the main process before the fork, then I sometimes get a crash with one of several different weird error messages from X, but this is very inconsistent. The direct cause of the bug seems to be the call to Tcl_FindExecutable in _tkinter's initialization code, which tells tcl the path of the python executable, but as a side effect triggers tcl into running some initialization routines earlier than it would do otherwise. Removing this call (which doesn't seem to have any adverse effects on my system) appears to "fix" the bug, but if anything else triggers tcl's initialization code before the fork (such as instantiating a tkinter.Tk object), the hang returns. I'm not really sure where else to go with this. I've attached a simplified python-3-compatible script displaying the problem in case someone else wants to have a look. |
I did a bit more digging and I think I've worked out what is going on. The particular bit of tcl initialization code that triggers the problem if it is run before the fork is Tcl_InitNotifier in tclUnixNotify.c. It turns out there is a known problem with this bit of tcl not being process-safe if tcl was built with threading support (this is discussed at https://bugs.archlinux.org/task/16401, for example). The bug doesn't show up in my 8.5 builds as threading support is off by default, though the debian/ubuntu packages apparently have it switched on. Threading was turned on by default in 8.6, but a recent change to tclUnixNotify.c (discussed at https://issues.apache.org/bugzilla/show_bug.cgi?id=55153#c13 - it should be included in 8.6.1 and 8.5.15) appears to have fixed the whole problem anyway. So hopefully the bug should disappear entirely in future releases of tcl, but for now you can work around it by building tcl without threads, calling exec in between the fork and any use of tkinter in the child process, or not importing tkinter until after the fork. I don't know if there should be a note about this somewhere in the tkinter docs? |
In 3.4 you can do this by using multiprocessing.set_start_method('spawn') |
Unable to reproduce on Ubuntu 12.04.5 with Python 2.7.8 and current libtk8.5 and libtcl8.5 releases using the attached hanger.py example. Key findings to-date:
The question was raised whether there should be a note added to the Tkinter module's docs about this situation. Because this issue is the result of particular versions on particular platforms built in a particular way and the issue appears addressed in current releases of those third party libraries, it probably makes good sense to track this sort of issue in the Tcl/Tk projects themselves and not in the Tkinter module's docs. If others encountering this issue in the future feel it is still too easy to end up with the right (wrong) combination of platform+tcl_version+build, they are encouraged to please open a new issue requesting a note be added to the documentation for Tkinter. Closing this issue, marking it as "third party". |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: