2012-05-25 40 views
5

El siguiente código se cuelga sin hacer nada en Python 3.2.2 en Linux:¿Por qué tkinter no funciona bien con multiprocesamiento?

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

La única información que he encontrado acerca de este problema es issue 5527, en el que se señala que el problema es con tkinter ser importados antes el proceso se bifurca, puede ser arreglado importando tkinter dentro de la función f, y que el problema ocurre en Linux pero no en Solaris.

¿Alguien sabe exactamente qué está causando este problema, y ​​si es intencional o finalmente se solucionará? ¿Hay alguna otra solución que no sea importar tkinter localmente en cualquier lugar que lo necesite (lo que parece un mal estilo)? ¿Algún otro módulo tiene problemas similares con multiprocesamiento?

+1

-0. Usted sabe el problema. Usted sabe que se ha presentado un informe de error. Usted conoce la solución. La única otra pregunta importante es "¿Algún otro módulo tiene problemas similares con el multiprocesamiento?", Que parece un poco abierto. –

+1

@StevenRumbalski: No conozco el problema: no tengo idea de qué está haciendo tkinter y no funciona aquí, o por qué depende de la plataforma. El informe de error se presentó hace más de 3 años, y no hay señales de que alguien sepa por qué (o en qué condiciones exactamente) sucede esto o cómo solucionarlo. Quizás mi última pregunta debería haber sido "¿hay algún otro módulo de biblioteca estándar que no se pueda importar antes de hornear un proceso?", Que es un poco más específico. – James

Respuesta

0

Mi sospecha es que el problema tiene que ver con la conexión al servidor X (generalmente un socket). Si esto se crea antes de que el proceso sea fork() -ed, el proceso hijo heredará esta conexión. Pero si trata de usarlo, el servidor X se confunde.

Después de un rápido vistazo a al Tkinter.py, parece que tal vez llamar a la función NoDefaultRoot antes de iniciar el proceso de podrían ser útiles. Todo depende de cuando se realiza la conexión al servidor X.

De lo contrario, la importación de Tkinter después de la horquilla parece ser el camino a seguir.

0

A partir de septiembre de 2013, hay algunos comentarios adicionales sobre el informe de errores que proporcionan más información sobre cuál es el problema real.

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

base en lo anterior, supongo que algo como lo siguiente que está sucediendo: Tkinter no es hilo de seguridad, por lo que (por cualquier razón) Tkinter quiere saber por cuál de es el hilo principal . Tkinter supone que el hilo principal cuando se carga el módulo Tkinter también será el hilo principal para la ejecución del programa. Cuando se bifurca o multiprocesamiento después de cargar Tkinter, esta suposición se rompe. (Por ejemplo, después de un tenedor, el hilo principal que se recuerda está en el elemento primario, no en el elemento secundario).

Cuestiones relacionadas