2012-05-25 2 views
5

Следующий код висит, ничего не делая в Python 3.2.2 в Linux:Почему tkinter отлично играет с многопроцессорной обработкой?

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() 

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

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

+1

-0. Вы знаете проблему. Вы знаете, что был отправлен отчет об ошибке. Вы знаете обходное решение. Единственный серьезный вопрос: «Есть ли у других модулей подобные проблемы с многопроцессорностью?», Что кажется немного открытым. –

+1

@StevenRumbalski: Я не знаю проблемы - я понятия не имею, что делает tkinter, который не работает здесь, или почему он зависит от платформы. Отчет об ошибке был подан более 3 лет назад, и нет никаких признаков того, что кто-нибудь знает, почему (или при каких именно условиях) это происходит или как это исправить. Может быть, мой последний вопрос должен был прочитать «есть ли какие-либо другие стандартные библиотечные модули, которые нельзя импортировать, прежде чем форсировать процесс», что немного более конкретно. – James

ответ

0

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

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

В противном случае импортирование Tkinter после того, как вилка, кажется, способ пойти.

0

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

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

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

Смежные вопросы