Вопрос по python – Почему tkinter не играет хорошо с многопроцессорностью?

5

Следующий код зависает, ничего не делая в python 3.2.2 в linux:

import tkinter
from multiprocessing import Process

def f():
    root = tkinter.Tk()
    label = tkinter.Label(root)
    label.pack()
    root.mainloop()

p = Process(target=f)
p.start()

Единственная информация, которую я нашел об этой проблеме,выпуск 5527, в котором отмечено, что проблема сtkinter импортируется до того, как процесс разветвляется, что это можно исправить, импортировавtkinter внутри функцииfи что проблема возникает в Linux, но не в Solaris.

Кто-нибудь знает, что именно вызывает эту проблему, и является ли она преднамеренной или в конечном итоге будет исправлена? Есть ли обходной путь, кроме импортаtkinter локально везде мне это нужно (что похоже на плохой стиль)? Есть ли у других модулей похожие проблемы с многопроцессорностью?

@ StevenRumbalski: Я не знаю проблемы - я понятия не имею, что делает tkinter, которая не работает здесь, или почему она зависит от платформы. Сообщение об ошибке было подано более 3 лет назад, и нет никаких признаков того, что кто-либо знает, почему (или при каких именно условиях) это происходит или как это исправить. Возможно, мой последний вопрос должен был прочитать "Есть ли какие-либо другие стандартные библиотечные модули, которые нельзя импортировать перед созданием процесса", что является более конкретным. James
-0. Вы знаете проблему. Вы знаете, что сообщение об ошибке было подано. Вы знаете обходной путь. Единственный важный вопрос: «Есть ли у других модулей аналогичные проблемы с многопроцессорностью?», Который кажется немного открытым. Steven Rumbalski

Ваш Ответ

2   ответа
0

дополнительных комментариев, которые дают более полное представление о том, что является реальной проблемой.

http://bugs.python.org/issue5527#msg194848
http://bugs.python.org/issue5527#msg195480

Исходя из вышеизложенного, я предполагаю, что происходит что-то вроде следующего: Tkinter не является потокобезопасным, поэтому (по любой причине) Tkinter хочет знать, какой поток является основным потоком. Tkinter предполагает, что основной поток при загрузке модуля Tkinter также будет основным потоком для выполнения программы. Когда вы форк или многопроцессный после загрузки Tkinter, это предположение нарушается. (Например, после разветвления запомненный основной поток находится в родительском, а не дочернем.)

0

что проблема связана с подключением к X-серверу (обычно это сокет). Если это создано до того, как процессfork()-ed, дочерний процесс наследует это соединение. Но если он пытается использовать его, X-сервер запутывается.

После беглого взгляда наTkinter.pyПохоже, зоветNoDefaultRoot функционировать перед началом процессаmight быть полезным. Все зависит отwhen соединение с X-сервером установлено.

В противном случае импорт Tkinter после разветвления кажется правильным.

Похожие вопросы